Как передать это по ссылке в С#?

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

Ответ 1

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

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

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

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

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

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

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


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

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

Ответ 2

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

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

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

public ClassB(ClassA master)
{
}
var slave = new ClassB(this);

Ответ 3

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

Ответ 4

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

ClassA m_classA;
public ClassB(ClassA classA)
{
   m_classA = classA;
}

Ответ 5

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