gpt4 book ai didi

c# - 如何将 "reference"分配给 C# 中的类字段?

转载 作者:IT王子 更新时间:2023-10-29 04:15:19 25 4
gpt4 key购买 nike

我正在尝试了解如何通过“引用”分配给 C# 中的类字段。

我要考虑以下示例:

 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 (Updated By Y)

而不是:

X (Updated By Y) (Updated By Z)

正如我所希望的那样。

似乎给一个字段赋一个“ref参数”就失去了引用。

有没有办法在分配给字段时保留引用?

最佳答案

正如其他人所指出的,您不能拥有“引用变量”类型的字段。但是,仅仅知道自己做不到可能并不令人满意;您可能还想首先知道为什么不,其次,如何绕过此限制。

之所以是因为只有三种可能:

1) 不允许引用类型的字段

2) 允许引用类型的不安全字段

3) 不要将临时存储池用于局部变量(又名“堆栈”)

假设我们允许 ref 类型的字段。那么你可以做

public ref int x;
void M()
{
int y = 123;
this.x = ref y;
}

现在可以在 M 完成后访问 y。这意味着要么我们在情况 (2) 中——访问 this.x 将崩溃并可怕地死去,因为 y 的存储不再存在——或者我们在情况 (3) 中,并且本地 y 存储在垃圾收集堆中,而不是临时内存池中。

我们喜欢将局部变量存储在临时池中的优化,即使它们是由 ref 传递的,我们讨厌这样的想法,即您可以在周围留下一个定时炸弹,这可能会使您的程序崩溃并在以后死亡。因此,选项一是:没有 ref 字段。

请注意,对于作为匿名函数的封闭变量的局部变量,我们选择选项 (3);这些局部变量不会分配到临时池之外。

这让我们想到了第二个问题:您如何解决这个问题?如果您想要 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.
}

好了。 y 存储在 gc 堆上,x 是一个具有获取和设置 y 能力的对象。

请注意,CLR 确实支持 ref 局部变量和 ref 返回方法,但 C# 不支持。也许假设的 C# future 版本将支持这些功能;我已经制作了它的原型(prototype)并且效果很好。但是,这在优先级列表中并不是真正的高,所以我不会抱太大希望。

更新:上一段中提到的功能最终在 C# 7 中真正实现了。但是,您仍然不能在字段中存储 ref。

关于c# - 如何将 "reference"分配给 C# 中的类字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2980463/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com