使用带有此关键字的ref参数?

时间:2010-04-15 16:13:25

标签: c# ref this-pointer

有没有办法强制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();
}

4 个答案:

答案 0 :(得分:10)

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

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

Visit(ref this);

该代码无法编译:“无法传递'&lt; this&gt;'作为ref或out参数,因为它是只读的“

答案 1 :(得分:5)

如果您的Visitor<T>是一个班级,那么您不需要ref关键字。

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

答案 2 :(得分:4)

听起来你已经得到了一个更大问题的答案。但无论如何我们要考虑这个。

  

有没有办法强制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参数传递,因此再次传递它没有问题。这样做几乎总是一个可怕的想法但它是合法的。

答案 3 :(得分:0)

你真的需要ref关键字吗?

如果更改接收器实例,

ref将非常有用 例如 receiver = null;

,否则

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