【问题标题】:Using a ref Parameter with the this Keyword?使用带有 this 关键字的 ref 参数?
【发布时间】:2010-04-15 16:13:25
【问题描述】:

有没有办法强制 this 关键字充当 ref 参数?我想传入一个修改对象多个属性的访问者,但这只是想像一个值参数一样。

对象中的代码:

public void Accept(Visitor<MyObject> visitor)
{
    visitor.Visit(this);
}

访客中的代码:

public void Visit(ref Visitor<MyObject> receiver)
{
    receiver.Property = new PropertyValue();
    receiver.Property2 = new PropertyValue();
}

【问题讨论】:

    标签: c# ref this-pointer


    【解决方案1】:

    由于您实际上并未更改 receiver 所指的内容,因此不需要 ref 关键字。但是,如果是这种情况,您将无法让 this 引用另一个实例。

    为了将this 作为ref 参数传递,您需要这样编写:

    Visit(ref this);
    

    该代码无法编译:“不能将 '' 作为 ref 或 out 参数传递,因为它是只读的”

    【讨论】:

    • 是的,你完全正确。但我希望原始类保留访问者所做的更改。如果我不作为 ref 传递,那么我不会只修改 copy 的属性吗?
    • @grefly:如果“this”是一个类,则不会。如果您不“访问”自定义结构(值类型),则不需要 ref。
    【解决方案2】:

    如果您的Visitor&lt;T&gt; 是一个类,那么您不需要ref 关键字。

    如果在方法中更改了类中的所有信息,则会自动更改它们

    【讨论】:

      【解决方案3】:

      听起来您已经对较大的问题有了答案。但无论如何,让我们考虑一下这个。

      有没有办法强制 this 关键字充当 ref 参数?

      是的。有逻辑地完成它。

      • ref 参数为变量创建一个别名
      • “this”不是引用类型中的变量
      • “this”是值类型中的变量
      • 因此,传递“ref this”的唯一方法是通过值类型的实例方法。

      事实上,这就是在幕后以值类型实现“this”的方式。当你有一个(最坏的做法!实际上不这样做)可变值类型时:

      struct S
      {
          private int x;
          public void M()
          {
              this.x = 123;
          }
      }
      ...
      S s = new S();
      s.M();
      

      既然 S 的实例是按值传递的,M 是如何改变 s 的? s 必须通过引用传递!事实上,我们生成的代码就像你写的一样:

      struct S
      {
          private int x;
          public static void M(ref S THIS)
          {
              THIS.x = 123;
          }
      }
      ...
      S s = new S();
      S.M(ref s);
      

      简而言之,结构中的“this”已经作为 ref 参数传递,因此再次传递它没有问题。这样做几乎总是一个可怕的想法,但这是合法的。

      【讨论】:

        【解决方案4】:

        你真的需要 ref 关键字吗?

        如果您更改接收器实例,ref 将很有用 例如 接收者 = null;

        否则

        receiver.Property 也可以在没有 ref 关键字的情况下访问

        【讨论】:

          猜你喜欢
          • 2014-11-21
          • 2017-10-25
          • 2011-10-13
          • 1970-01-01
          • 2012-11-10
          • 1970-01-01
          • 2013-12-10
          • 2018-04-26
          • 1970-01-01
          相关资源
          最近更新 更多