22 Stimmen

Was bedeuten ref, val und out bei Methodenparametern?

Ich möchte eine klare, knappe und präzise Antwort erhalten.

Idealerweise als die eigentliche Antwort, obwohl Links zu guten Erklärungen willkommen sind.

Dies gilt auch für VB.Net, aber die Schlüsselwörter sind anders - ByRef y ByVal .

27voto

Zooba Punkte 10867

Standardmäßig (in C#) wird bei der Übergabe eines Objekts an eine Funktion eine Kopie des Verweises auf dieses Objekt übergeben. Die Änderung des Parameters selbst ändert nur den Wert im Parameter und nicht die angegebene Variable.

void Test1(string param)
{
    param = "new value";
}

string s1 = "initial value";
Test1(s1);
// s1 == "initial value"

Verwendung von out o ref übergibt einen Verweis auf die im Funktionsaufruf angegebene Variable. Jede Änderung des Wertes einer out o ref Parameter wird an den Aufrufer zurückgegeben.

Beide out y ref verhalten sich bis auf einen kleinen Unterschied identisch: ref Parameter müssen vor dem Aufruf initialisiert werden, während out Parameter können uninitialisiert sein. Durch Erweiterung, ref Parameter sind garantiert zu Beginn der Methode initialisiert, während out Parameter werden als nicht initialisiert behandelt.

void Test2(ref string param)
{
    param = "new value";
}

void Test3(out string param)
{
    // Use of param here will not compile
    param = "another value";
}

string s2 = "initial value";
string s3;
Test2(ref s2);
// s2 == "new value"
// Test2(ref s3); // Passing ref s3 will not compile
Test3(out s2);
// s2 == "another value"
Test3(out s3);
// s3 == "another value"

bearbeiten : Wie dp weist darauf hin, dass der Unterschied zwischen out y ref wird nur vom C#-Compiler durchgesetzt, nicht von der CLR. Soweit ich weiß, hat VB keine Entsprechung für out und implementiert ref (als ByRef ), was der Unterstützung durch die CLR entspricht.

8voto

denis phillips Punkte 12174

Eine zusätzliche Anmerkung zu ref vs. out: Die Unterscheidung zwischen den beiden wird durch den C#-Compiler erzwungen. Die CLR unterscheidet nicht zwischen out und ref. Dies bedeutet, dass Sie nicht zwei Methoden haben können, deren Signaturen sich nur durch ein out oder ref

void foo(int value) {}

// Only one of the following would be allowed

// valid to overload with ref
void foo(ref int value) {}

// OR with out
void foo(out int value) {}

3voto

Keith Punkte 141163

out bedeutet, dass der Parameter von der Methode initialisiert wird:

int result; //not initialised

if( int.TryParse( "123", out result ) )
   //result is now 123
else
   //if TryParse failed result has still be 
   // initialised to its default value (0)

ref erzwingt die Übergabe der zugrunde liegenden Referenz:

void ChangeMyClass1( MyClass input ) {
   input.MyProperty = "changed by 1";
   input = null;
   //can't see input anymore ... 
   // I've only nulled my local scope's reference
}

void ChangeMyClass2( ref MyClass input ) {
   input.MyProperty = "changed by 2";
   input = null;
   //the passed reference is now null too.
}

MyClass tester = new MyClass { MyProperty = "initial value" };

ChangeMyClass1( tester );
// now tester.MyProperty is "changed by 1"

ChangeMyClass2( ref tester );
// now tester is null

2voto

sven Punkte 17688

Eine meiner eigenen Fragen bei stackoverflow behandelt dieses Thema ebenfalls.
Es verarbeitet etwa "Übergabe durch Verweis" und "Übergabe durch Wert" in verschiedenen Arten von Sprachen, c# ist enthalten Vielleicht finden Sie dort auch einige zusätzliche Informationen.

Im Grunde läuft es darauf hinaus:

  • ref: es wird der Parameter mit dem Schlüsselwort ref übergeben durch Verweis
  • out: der Parameter mit dem Schlüsselwort out wird als Ausgabeparameter

aber das ist wirklich die grundlegendste Antwort, die man geben kann, denn es ist ein wenig komplexer als hier angegeben

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X