2010-04-15 3 views
5

Есть ли способ заставить это ключевое слово действовать как аргумент ref? Я хотел бы передать посетителю, который изменяет несколько свойств объекта, но это только хочет действовать как параметр значения.Использование параметра ref с этим ключевым словом?

код в объекте:

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

Код в Visitor:

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

ответ

10

Так как вы на самом деле не меняется, что receiver относится к нет необходимости в ref ключевого слова. Однако, если бы это было так, вы не смогли бы сделать this ссылкой на другой экземпляр.

Для того, чтобы пройти this в качестве параметра ref, вам нужно будет написать так:

Visit(ref this); 

Этот код не будет компилироваться: «Невозможно передать„< это >“как исх или вне аргумент, потому что он доступен только для чтения "

+0

Да, вы совершенно правы. Но я хочу, чтобы первоначальный класс сохранял изменения, внесенные посетителем. Если я не передаю как ref, то не могу ли я изменить свойства * копии * ? – grefly

+0

@grefly: Нет, если «это» - класс. Если вы не «посещаете» настраиваемую структуру (типы значений), ref не требуется. –

+0

Спасибо, ты в порядке! – grefly

5

Если ваш Visitor<T> является классом, то вам не нужно ключевое слово ref.

Вся информация внутри класса автоматически изменяется, если они изменяются в методе

+0

Это правильно - извините, я не могу отметить оба как ответы. – grefly

0

ли вам действительно нужно реф ключевое слово?

ref был бы полезен, если вы замените экземпляр приемника , например. receiver = null;

иначе

receiver.Property доступен также без реф ключевого слова

4

Это звучит, как вы получили ответ на ваш вопрос уже большего. Но давайте рассмотрим этот вариант.

Есть ли способ заставить это ключевое слово действовать как аргумент ref?

Да. Работайте это логически.

  • реф аргумент делает псевдоним для переменной.
  • «этот» не является переменной в ссылочного типа
  • «это» является переменной в типе значения
  • поэтому единственный способ передать «реф это» от метода экземпляра типа значения ,

И на самом деле это то, как «это» реализовано в виде значений за кулисами. Когда у вас есть (худшая практика!на самом деле не делать этого) изменяемый тип значения:

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); 

Короче говоря, «это» в структуры уже передается в качестве параметра реф, так что нет никаких проблем, проходя его вдоль еще раз. Это почти всегда ужасная идея, но это законно.