Используя параметр ref с этим ключевым словом? - PullRequest
5 голосов
/ 15 апреля 2010

Есть ли способ заставить ключевое слово 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 ]

10 голосов
/ 15 апреля 2010

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

Чтобы передать this в качестве параметра ref, вам нужно написать его следующим образом:

Visit(ref this);

Этот код не будет компилироваться: "Невозможно передать '' в качестве аргумента ref или out, поскольку он доступен только для чтения"

5 голосов
/ 15 апреля 2010

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

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

4 голосов
/ 16 апреля 2010

Похоже, вы уже получили ответ на свой более крупный вопрос. Но давайте все равно рассмотрим это.

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

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

  • Аргумент ref создает псевдоним для переменной .
  • «this» не является переменной в ссылочном типе
  • «this» является переменной в типе значения
  • поэтому единственный способ передать «ref 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, поэтому нет проблем с его повторной передачей. Это почти всегда ужасная идея , но это законно.

0 голосов
/ 15 апреля 2010

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

ref будет полезно, если вы измените экземпляр получателя, например, receive = null;

, в противном случае

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

...