2010-04-15 61 views
5

有没有办法强制这个关键字充当ref参数?我想传入一个修改对象上多个属性的访问者,但这只是想像一个值参数。使用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(); 
} 

回答

10

既然你实际上并没有改变什么receiver是指没有必要为ref关键字。但是,如果情况确实如此,您将无法使this引用另一个实例。

为了通过this作为ref参数,你就需要把它写这样的:

Visit(ref this); 

该代码将无法编译:“不能通过‘<这>’作为ref或出因为它是只读的“

+0

是的,你完全正确。但我希望原始课程保留访问者所做的更改。如果我没有通过参考,那么我是不是只会修改的*副本*的属性? – grefly 2010-04-15 16:25:32

+0

@grefly:如果“this”是一个类,则不会。假设你不“访问”自定义结构(值类型),ref不是必需的。 – 2010-04-15 16:28:40

+0

谢谢,你完全正确! – grefly 2010-04-15 16:30:20

5

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

所有类内部信息,如果他们的方法

+0

这是正确的 - 我很抱歉,我不能标记为答案。 – grefly 2010-04-15 16:30:39

0

你真的需要ref关键字改变自动改变?

如果您更改接收器实例 (例如, receiver = null;

否则

receiver.Property也没有访问ref关键字

4

这听起来像你得到的回答你的更大的问题了。但是,无论如何我们都要考虑这一点。

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

是的。通过逻辑工作。

  • 一个REF参数使得一个可变一个别名
  • “这个”不是引用类型
  • 变量“这”是一个值类型
  • 因此
  • 一个变量来传递“REF这个”的唯一方法是从一个值类型的实例方法。

而事实上这就是“this”是如何在幕后值类型中实现的。当你有一个(最坏的做法!没有真正做到这一点),可变的值类型:

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

由于S的实例按值传递它是如何的M变异S'必须通过引用传递!其实我们生成的代码是一样,如果你写的东西,如:

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

总之,一个“本”中已经被作为ref参数传递,所以没有一起传递问题一个结构再次。这样做几乎总是一个可怕的想法,但它是合法的。