Как передать это по ссылке в C #? - PullRequest
12 голосов
/ 30 июня 2011

В моем классе (ClassA) я хочу создать связанный экземпляр другого класса (ClassB), предоставив ему ссылку на объект, который инициировал его создание.Поэтому я предоставил ClassB конструктор, принимающий аргумент (ref ClassB master).Но в ClassA я не могу просто назвать var slave = new ClassB (см. Это).Как это реализовать?

Ответы [ 5 ]

24 голосов
/ 30 июня 2011

Ключевое слово ref вызывает Передача по ссылке семантика - то есть , если переменная переназначена в вызываемой функции, она будет переназначена переменная также в вызывающем .

Очевидно, это работает, только если переменная 2 (которая может быть переназначена)to) напрямую передается в качестве аргумента и не будет работать, если передано произвольное выражение.В этом случае this не является переменной, а является специальным выражением, которое не может быть переназначено и поэтому не может использоваться.

Как таковое, это будет работать: (Но, пожалуйста, смотрите другие ответы и сохраняйтечитая о том, почему это вероятно не требуется и / или просто глупо.)

var me = this;
var slave = new ClassB(ref me);

Однако проход по ref erence не следует путать с Обход объекта [Обмен] 1 семантика.Обход объекта означает, что , если объект передан, , что объект, переданный : объект не скопирован / клонирован / дублирован. Если объект видоизменен, то объект видоизменен. Все Типы ссылок имеют семантику Pass by Object в C #, если только не refили out используются.(Ключевое слово class объявляет новый ссылочный тип, как в случае с сообщением).

С другой стороны, Типы значений (например, struct), включая int и Guid и KeyValuePair<K,V>, имеют Передать по значению семантика - в этом случае создается копия и, таким образом, , если значение изменено, только значениеСтруктура (которая является копией) изменяется .

Счастливое кодирование


1 Под C # /. NET достигает Pass by Object, передавая ссылка на объект по значению.Однако вышеприведенные правила правильно описывают наблюдаемую семантику и эффекты.

2 В отличие от C #, который позволяет использовать переменные только с ref, VB.NET позволяет использовать свойства.Компилятор VB.NET автоматически создает временную переменную и неявные инструкции чтения / записи свойства во время компиляции.

9 голосов
/ 30 июня 2011

ref относится к ссылкам на переменные, а не к объектным ссылкам.

Если вы просто хотите передать ссылку на объект, ключевое слово ref не обязательно. Объекты уже являются ссылочными типами, поэтому их ссылки передаются по значению. Сами объекты не копируются.

Итак, вам не нужно ни ключевое слово ref ни в конструкторе, ни в экземпляре:

public ClassB(ClassA master)
{
}
var slave = new ClassB(this);
1 голос
/ 30 июня 2011

Вам действительно нужно ключевое слово ref? Все типы в основном передаются по ссылке, поэтому если у вас есть ClassB, берущий ClassA в качестве аргумента конструктора, просто передайте новый ClassB (this), нет необходимости использовать ref.

1 голос
/ 30 июня 2011

Вы не можете изменить указатель this, что разрешено ключевым словом ref. Почему вы не можете объявить ClassB таким образом?

ClassA m_classA;
public ClassB(ClassA classA)
{
   m_classA = classA;
}
1 голос
/ 30 июня 2011

Вам не нужно проходить мимо ref в этом случае.Если вы передаете ClassB (this), он будет передан по ссылке, а не по значению.Любые изменения, внесенные в экземпляр classA, переданные в конструктор classB, будут применены и к классу A.

...