2009-06-19 15 views

Antwort

14
  • Sie verwenden Ref, wenn Sie einen initialisierten Parameter übergeben und Sie erwarten, dass die Methode/Funktion, ihn zu ändern.
  • Sie verwenden Out, wenn Sie einen nicht initialisierten Parameter übergeben und die Methode diesen Parameter initialisieren und füllen muss (Sie erhalten sonst eine Warnung oder einen Fehler).

    bool IsUserValid (Zeichenfolgename);

    void IsUserValid (Zeichenfolgename, aus bool gültig);

Die obigen Deklarationen sind in etwa gleich. Es ist einfacher, den Wert zurückzugeben. In diesem Fall verwenden Sie den Rückgabetyp. Aber wenn Ihre Methode auch das Geburtsdatum des Benutzers zurückgeben muss, können Sie nicht beide Parameter in der Rückgabe zurückgeben, Sie müssen out Parameter verwenden, um eine von ihnen zurückzugeben (oder die Methode ungültig machen und beide als out zurückgeben).

+0

Perfekte Erklärung prägnant und leicht zu verstehen Danke – Marin

1

was für eine bessere Art und Weise Sie Sie eine MSDN link geben zu zeigen;)

von diesem Link:

Der Unterschied zwischen ref und aus ist subtile, aber wichtige. Jeder Parameter-Passing-Modus ist so ausgelegt, dass er sich auf ein etwas anderes Programmier-Szenario bezieht. Der wichtige Unterschied zwischen out- und ref-Parametern besteht in den eindeutigen Zuordnungsregeln, die von jedem verwendet werden.

2

Eine Sache, auf die man achten sollte, ist, wann (nicht) "ref" mit Referenztyp-Parametern zu verwenden ist. Das "ref" ist für die Referenz selbst, nicht für den Inhalt des Objekts, auf das die Referenz verweist.

Wenn Sie eine Referenz "nach Wert" übergeben (dh ohne 'ref' oder 'out'), können Sie die Referenz nicht ändern (so ein "neues" wird den Anruf nicht überleben), Sie kann aber noch die Werte der Eigenschaften ändern, auf die diese Referenz verweist (falls die Klasse dies zulässt).

1

Es ist im Allgemeinen verpönt, (out) und ref zu verwenden (oder missbrauchen), oft ist es viel sauberer, eine Struktur oder einfache Klasse zurückzugeben, die die mehreren Felder enthält, die Sie "zurückgeben" müssen.

Wie für ref vs. out, erfordert out eine nicht initialisierte Variable, und der Code wird nicht kompiliert, es sei denn, Sie setzen den out-Parameter vor dem Verlassen der Funktion.

Der folgende Code wird daher nicht Kompilierung:

bool TryParse(string text, out int result) 
{ 
    if (text == null) 
    return false; 
    else 
    { 
    // do the parsing 
    } 
} 

ref die Sie nicht verlangen, daß sie setzen. Auch wie Hans erwähnt, können Sie das Objekt eines Referenztyps tatsächlich "neu" verwenden, wenn Sie ref verwenden (da Sie eine Referenz auf die Referenz erhalten, die in etwa einem Objekt ** in C++ entspricht).

0

Wirklich, es gibt 3 Möglichkeiten, einen Parameter an eine Methode zu übergeben: durch Referenz, nach Wert und als Ausgabe.

von Wert der Standard ist und nicht über ein Schlüsselwort in C# (es tut in VB.Net: ByVal) - es geht um eine Kopie von Werttypen:

public void SomeMethod1(int num) 
{ 
    num = 2; 
} 

int myNum = 1; 
SomeMethod1(myNum ); 
// myNum is still 1, we just set a new one 

Verwirrend - von Wert übergibt eine Kopie der Referenz für Referenztypen. Das bedeutet, dass die Änderungen an einen Referenztyp Punkt zurück auf die Instanz, aber Sie haben nur eine Kopie des aktuellen Zeiger auf die Referenz haben:

public void SomeMethod1(MyClass instance) 
{ 
    // changes the name on the instance 
    instance.Name = "test 1"; 

    // we're only nulling the copy passed to this method 
    instance = null; 
} 

public void SomeMethod2(MyClass instance) 
{ 
    // changes the name on the instance 
    instance.Name = "test 2"; 

    // this is a new instance only in this method 
    instance = new MyClass { Name = "new instance" }; 
} 

MyClass myInst = new MyClass { Name = "original" }; 
SomeMethod1(myInst); 
// myInst.Name is now "test 1" 

SomeMethod2(myInst); 
// myInst.Name is now "test 2" 

Ok, jetzt durch Bezugnahme (ref in C# oder ByRef in VB.Net) übergibt einen Verweis auf den Wert für structs:

public void SomeMethod1(ref int num) 
{ 
    num = 2; 
} 

int myNum = 1; 
SomeMethod1(ref myNum ); 
// myNum is now 2, we changed the reference 

Einfach genug, aber für Referenztypen durch Bezugnahme übergibt den aktuellen Zeiger auf die Instanz, keine Kopie:

public void SomeMethod1(ref MyClass instance) 
{ 
    // changes the name on the instance 
    instance.Name = "test 1"; 

    // we're nulling the reference passed to this method 
    instance = null; 
} 

public void SomeMethod2(ref MyClass instance) 
{ 
    // changes the name on the instance 
    instance.Name = "test 2"; 

    // this is a new instance replacing the original 
    instance = new MyClass { Name = "new instance" }; 
} 

MyClass myInst = new MyClass { Name = "original" }; 
SomeMethod1(ref myInst); 
// myInst.Name will now throw a NullReferenceException because myInst is null 

SomeMethod2(ref myInst); 
// myInst.Name is now "new instance" 

So, während beide durch Bezugnahme und von Wert für Referenztypen ähnlich sind, ist das Verhalten sehr deutlich, wenn Sie die Referenz ändern sich selbst (und nicht als das, was Sie sich beziehen).

Schließlich als Ausgabe ist eine zusätzliche Rückgabevariable, genau wie die tatsächliche Rückkehr. Diese beiden sind bascially gleich:

public int SomeMethod1() 
{ 
    return 1; 
} 

public void SomeMethod2(out int num) 
{ 
    num = 1; 
} 

Wenn Sie einen Out-Parameter es mit dem Verfahren aufgefüllt werden muss (wie bei einem Return).

Verwandte Themen