首頁 >後端開發 >C++ >為什麼在 C# 中無法透過引用將值傳遞給類別欄位以及如何實現類似的行為?

為什麼在 C# 中無法透過引用將值傳遞給類別欄位以及如何實現類似的行為?

Susan Sarandon
Susan Sarandon原創
2025-01-05 22:38:40651瀏覽

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

在C 中透過引用將值傳遞給類別欄位

在C# 中,透過引用為類別欄位賦值似乎可以使用ref 來實現 參數修飾符。然而,這種技術在分配給欄位時無法保留引用。

問題

考慮以下程式碼片段:

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();

預期輸出是兩個更新都應用於字串:「X(由Y 更新)(由Z 更新)”,但實際輸出僅為“X(由Y 更新)”。這就提出了在分配給欄位時如何維護引用的問題。

答案

限制源自於 C# 不允許 ref 類型的欄位。此約束迫使您在完全禁止 ref 欄位或允許可能導致崩潰的不安全欄位之間進行選擇。此外,使用局部變數的暫存池(堆疊)會與存取方法完成後可能不再存在的值發生衝突。

為了避免這些問題,C# 禁止ref 欄位並建議使用 getter 和setter 方法 取代:

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.
}

使用這種方法,x 有效成為一個能夠取得和設定y 值的對象,即使y 存放在垃圾回收堆上。

而 C# 不直接支援 ref 傳回方法和 ref 參數,該功能已在 C# 7 中實作。但是,仍然存在 ref 類型不能用作欄位的限制。

以上是為什麼在 C# 中無法透過引用將值傳遞給類別欄位以及如何實現類似的行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn