如何通过“引用”将其分配给c#中的类字段?

如何通过“引用”将其分配给c#中的类字段?

我试图了解如何通过“引用”分配给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(由Y更新)

并不是:

X(由Y更新)(由Z更新)

正如我所希望的那样。

似乎为字段分配“ref参数”会丢失引用。

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

谢谢。


守候你守候我
浏览 497回答 3
3回答

30秒到达战场

正如其他人所指出的那样,你不能拥有“ref to variable”类型的字段。然而,只知道你不能做到这一点可能并不令人满意;&nbsp;你可能也想先知道,为什么不知道,其次,如何解决这个限制。原因是因为只有三种可能性:1)禁止ref类型的字段2)允许ref类型的不安全字段3)不要将临时存储池用于局部变量(也称为“堆栈”)假设我们允许ref类型的字段。然后你可以做到public&nbsp;ref&nbsp;int&nbsp;x;void&nbsp;M(){ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;y&nbsp;=&nbsp;123; &nbsp;&nbsp;&nbsp;&nbsp;this.x&nbsp;=&nbsp;ref&nbsp;y;}现在可以在M完成后访问y&nbsp;。这意味着要么我们遇到(2) - 访问this.x将崩溃并且死亡可怕因为y的存储不再存在 - 或者我们遇到(3),并且本地y存储在垃圾收集堆上,而不是临时内存池。我们喜欢将局部变量存储在临时池中的优化,即使它们是由ref传递的,我们也不喜欢你可能会留下定时炸弹,这可能会导致程序崩溃并在以后死亡。因此,选项一是:没有引用字段。注意,对于作为匿名函数的封闭变量的局部变量,我们选择option(3);&nbsp;这些局部变量不会从临时池中分配出来。这就引出了第二个问题:你如何解决这个问题?如果你想要一个ref字段的原因是制作另一个变量的getter和setter,那就完全合法了:sealed&nbsp;class&nbsp;Ref<T>{ &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;Func<T>&nbsp;getter; &nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;Action<T>&nbsp;setter; &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Ref(Func<T>&nbsp;getter,&nbsp;Action<T>&nbsp;setter) &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.getter&nbsp;=&nbsp;getter; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.setter&nbsp;=&nbsp;setter; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;T&nbsp;Value&nbsp;{&nbsp;get&nbsp;{&nbsp;return&nbsp;getter();&nbsp;}&nbsp;set&nbsp;{&nbsp;setter(value);&nbsp;}&nbsp;}}...Ref<int>&nbsp;x;void&nbsp;M(){ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;y&nbsp;=&nbsp;123; &nbsp;&nbsp;&nbsp;&nbsp;x&nbsp;=&nbsp;new&nbsp;Ref<int>(()=>y,&nbsp;z=>{y=z;}); &nbsp;&nbsp;&nbsp;&nbsp;x.Value&nbsp;=&nbsp;456; &nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(y);&nbsp;//&nbsp;456&nbsp;--&nbsp;setting&nbsp;x.Value&nbsp;changes&nbsp;y.}你去吧&nbsp;y存储在gc堆上,x是一个能够获取和设置的对象y。请注意,CLR确实支持ref本地和ref返回方法,但C#不支持。也许C#的假设未来版本将支持这些功能;&nbsp;我有它的原型,它运作良好。但是,这在优先级列表中并不是很高,所以我不会抱有希望。更新:上面段落中提到的功能最终在C#7中实现了。但是,您仍然无法在某个字段中存储引用。
打开App,查看更多内容
随时随地看视频慕课网APP