Sie hängt vom Kompilierkontext ab (siehe Beispiel unten).
out
y ref
bezeichnen beide die Übergabe von Variablen durch Verweis, doch ref
erfordert, dass die Variable vor der Übergabe initialisiert wird, was ein wichtiger Unterschied im Zusammenhang mit Marshaling sein kann (Interop: UmanagedToManagedTransition oder umgekehrt)
MSDN warnt :
Verwechseln Sie das Konzept der Übergabe durch Referenz nicht mit dem Konzept der Referenztypen. Die beiden Konzepte sind nicht identisch. Ein Methodenparameter kann durch ref geändert werden, unabhängig davon, ob es sich um einen Werttyp oder einen Referenztyp handelt. Bei der Referenzübergabe wird ein Wertetyp nicht gepackt.
Aus den offiziellen MSDN Docs:
Das Schlüsselwort out bewirkt, dass die Argumente als Referenz übergeben werden. Dies ist ähnlich wie das ref-Schlüsselwort, mit dem Unterschied, dass ref erfordert, dass die Variable initialisiert wird, bevor sie übergeben wird
Das Schlüsselwort ref bewirkt, dass ein Argument als Referenz und nicht als Wert übergeben wird. Die Übergabe per Verweis hat zur Folge, dass jede Änderung des Parameters in der Methode sich in der zugrunde liegenden Argumentvariablen in der aufrufenden Methode niederschlägt. Der Wert eines Referenzparameters ist immer derselbe wie der Wert der zugrunde liegenden Argumentvariablen.
Wir können überprüfen, ob out und ref tatsächlich dasselbe sind, wenn das Argument zugewiesen wird:
CIL Beispiel :
Betrachten Sie das folgende Beispiel
static class outRefTest{
public static int myfunc(int x){x=0; return x; }
public static void myfuncOut(out int x){x=0;}
public static void myfuncRef(ref int x){x=0;}
public static void myfuncRefEmpty(ref int x){}
// Define other methods and classes here
}
in CIL, die Anweisungen von myfuncOut
y myfuncRef
sind erwartungsgemäß identisch.
outRefTest.myfunc:
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: starg.s 00
IL_0004: ldarg.0
IL_0005: stloc.0
IL_0006: br.s IL_0008
IL_0008: ldloc.0
IL_0009: ret
outRefTest.myfuncOut:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.0
IL_0003: stind.i4
IL_0004: ret
outRefTest.myfuncRef:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldc.i4.0
IL_0003: stind.i4
IL_0004: ret
outRefTest.myfuncRefEmpty:
IL_0000: nop
IL_0001: ret
nop : kein Betrieb, ldloc : lokal laden, stloc : Stapel lokal, ldarg : Argument laden, Der Teufel steckt im Detail. Verzweigung zum Ziel....
(Siehe: Liste der CIL-Anweisungen )