Ich verstehe , dass , wenn ich einen Wert vom Typ Pass ( int
, struct
, etc.) als Parameter (ohne das ref
Schlüsselwort), wird eine Kopie dieser Variablen auf die Methode übergeben wird, aber wenn ich die Verwendung ref
Schlüsselwort ein Verweis auf diese Variable übergeben wird , kein neuer.
Bei Referenztypen wie Klassen wird jedoch auch ohne das ref
Schlüsselwort eine Referenz an die Methode übergeben, keine Kopie. Wozu dient das ref
Schlüsselwort bei Referenztypen?
Nehmen Sie zum Beispiel:
var x = new Foo();
Was ist der Unterschied zwischen den folgenden?
void Bar(Foo y) {
y.Name = "2";
}
und
void Bar(ref Foo y) {
y.Name = "2";
}
c#
parameters
pass-by-reference
pass-by-value
Andreas Grech
quelle
quelle
Es gibt Fälle, in denen Sie die tatsächliche Referenz und nicht das Objekt ändern möchten, auf das verwiesen wird:
quelle
Jon Skeet hat einen großartigen Artikel über die Parameterübergabe in C # geschrieben. Es beschreibt klar das genaue Verhalten und die Verwendung der Übergabe von Parametern nach Wert, Referenz (
ref
) und Ausgabe (out
).Hier ist ein wichtiges Zitat von dieser Seite in Bezug auf
ref
Parameter:quelle
Sehr schön hier erklärt: http://msdn.microsoft.com/en-us/library/s6938f28.aspx
Auszug aus dem Artikel:
quelle
Wenn Sie einen Referenztyp mit dem Schlüsselwort ref übergeben, übergeben Sie die Referenz als Referenz, und die von Ihnen aufgerufene Methode kann dem Parameter einen neuen Wert zuweisen. Diese Änderung wird auf den aufrufenden Bereich übertragen. Ohne ref wird die Referenz als Wert übergeben, und dies geschieht nicht.
C # hat auch das Schlüsselwort 'out', das ref sehr ähnlich ist, außer dass mit 'ref' Argumente vor dem Aufruf der Methode initialisiert werden müssen und mit 'out' Sie einen Wert in der empfangenden Methode zuweisen müssen.
quelle
Hier können Sie die übergebene Referenz ändern, z
Sie können auch verwenden , wenn Sie sich nicht für die übergebene Referenz interessieren:
quelle
Noch ein Haufen Code
quelle
Zusätzlich zu den vorhandenen Antworten:
Wie Sie nach dem Unterschied der beiden Methoden gefragt haben: Es gibt keine Co (ntra) -Varianz bei der Verwendung von
ref
oderout
:quelle
Ein Parameter in einer Methode scheint immer eine Kopie zu übergeben, die Frage ist eine Kopie von was. Eine Kopie wird von einem Kopierkonstruktor für ein Objekt erstellt. Da alle Variablen in C # Objekt sind, glaube ich, dass dies für alle der Fall ist. Variablen (Objekte) sind wie Menschen, die an bestimmten Adressen leben. Wir ändern entweder die Personen, die an diesen Adressen leben, oder wir können weitere Verweise auf die Personen erstellen, die an diesen Adressen im Telefonbuch leben (flache Kopien erstellen). Es kann also mehr als eine Kennung auf dieselbe Adresse verweisen. Referenztypen benötigen mehr Speicherplatz. Im Gegensatz zu Werttypen, die direkt durch einen Pfeil mit ihrer Kennung im Stapel verbunden sind, haben sie einen Wert für eine andere Adresse im Heap (einen größeren Speicherplatz zum Verweilen). Dieser Platz muss vom Haufen genommen werden.
Werttyp: Einrücker (enthält Wert = Adresse des Stapelwerts) ----> Wert des Werttyps
Referenztyp: Bezeichner (enthält Wert = Adresse des Stapelwerts) ----> (enthält Wert = Adresse des Heap-Werts) ----> Heap-Wert (enthält meistens Adressen zu anderen Werten), stellen Sie sich vor, dass mehr Pfeile in verschiedenen Bereichen stecken Richtungen zu Array [0], Array [1], Array [2]
Die einzige Möglichkeit, einen Wert zu ändern, besteht darin, den Pfeilen zu folgen. Wenn ein Pfeil verloren geht oder geändert wird, ist der Wert nicht erreichbar.
quelle
Referenzvariablen tragen die Adresse von einem Ort zum anderen, sodass jede Aktualisierung an jedem Ort alle Orte widerspiegelt, DANN was die Verwendung von REF ist. Die Referenzvariable (405) ist so lange gültig, bis der in der Methode übergebenen Referenzvariablen kein neuer Speicher zugewiesen wird.
Sobald ein neuer Speicher zugewiesen wurde (410), wird die Wertänderung für dieses Objekt (408) nicht überall wiedergegeben. Dafür kommt ref. Ref ist eine Referenzreferenz. Wenn also ein neuer Speicher zugewiesen wird, wird er bekannt, da er auf diesen Speicherort verweist. Daher kann der Wert von everyOne gemeinsam genutzt werden. Sie können das Bild für mehr Klarheit sehen.
quelle