Heim >Backend-Entwicklung >C++ >Warum funktioniert die Übergabe von Werten an Klassenfelder per Referenz in C# nicht und wie kann ich ein ähnliches Verhalten erreichen?
In C# mag es so aussehen, als ob die Zuweisung von Werten an Klassenfelder per Referenz mithilfe von ref erreicht werden kann Parametermodifikator. Diese Technik schafft es jedoch nicht, die Referenz bei der Zuweisung zu einem Feld beizubehalten.
Bedenken Sie den folgenden Codeausschnitt:
public class X { public X() { string example = "X"; new Y(ref example); new Z(ref example); System.Diagnostics.Debug.WriteLine(example); } } public class Y { public Y(ref string example) { example += " (Updated By Y)"; } } public class Z { private string _Example; public Z(ref string example) { this._Example = example; this._Example += " (Updated By Z)"; } } var x = new X();
Die erwartete Ausgabe ist zu sehen Beide Aktualisierungen wurden auf die Zeichenfolge angewendet: „X (Aktualisiert von Y) (Aktualisiert von Z)“, aber die tatsächliche Ausgabe ist nur „X (Aktualisiert von Y)“. Dies wirft die Frage auf, wie die Referenz bei der Zuweisung zu einem Feld beibehalten werden soll.
Die Einschränkung ergibt sich aus der Tatsache, dass C# keine Felder vom Typ „ref“ zulässt. Diese Einschränkung erzwingt die Wahl zwischen dem vollständigen Verbieten von Ref-Feldern oder dem Zulassen unsicherer Felder, die möglicherweise zu Abstürzen führen könnten. Darüber hinaus würde die Verwendung des temporären Speicherpools für lokale Variablen (des Stapels) zu Konflikten mit dem Zugriff auf Werte führen, die nach Abschluss der Methode möglicherweise nicht mehr vorhanden sind.
Um diese Probleme zu vermeiden, verbietet C# Referenzfelder und empfiehlt die Verwendung von Getter- und Setter-Methoden stattdessen:
sealed class Ref<T> { private readonly Func<T> getter; private readonly Action<T> setter; public Ref(Func<T> getter, Action<T> setter) { this.getter = getter; this.setter = setter; } public T Value { get { return getter(); } set { setter(value); } } } ... Ref<int> x; void M() { int y = 123; x = new Ref<int>(() => y, z => { y = z; }); x.Value = 456; Console.WriteLine(y); // 456 -- setting x.Value changes y. }
Mit diesem Ansatz wird x effektiv zu einem Objekt, das hat die Möglichkeit, den Wert von y abzurufen und festzulegen, auch wenn y auf dem Garbage-Collected-Heap gespeichert ist.
Während C# Ref-Rückgabemethoden nicht direkt unterstützt und Ref-Parameter wurde diese Funktion in C# 7 implementiert. Es bleibt jedoch eine Einschränkung, dass Ref-Typen nicht als Felder verwendet werden können.
Das obige ist der detaillierte Inhalt vonWarum funktioniert die Übergabe von Werten an Klassenfelder per Referenz in C# nicht und wie kann ich ein ähnliches Verhalten erreichen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!