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?

Warum funktioniert die Übergabe von Werten an Klassenfelder per Referenz in C# nicht und wie kann ich ein ähnliches Verhalten erreichen?

Susan Sarandon
Susan SarandonOriginal
2025-01-05 22:38:40622Durchsuche

Why Doesn't Passing Values to Class Fields by Reference Work in C# and How Can I Achieve Similar Behavior?

Übergabe von Werten an Klassenfelder per Referenz in C

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.

Das Problem

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 Antwort

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn