首页 > 后端开发 > C++ > 为什么在 C# 中无法通过引用将值传递给类字段以及如何实现类似的行为?

为什么在 C# 中无法通过引用将值传递给类字段以及如何实现类似的行为?

Susan Sarandon
发布: 2025-01-05 22:38:40
原创
655 人浏览过

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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板