Назначение множества переменных в одной строке кода C #

Я не уверен в том, что называется операцией, которую я хочу сделать на C #, но я знаю, что это можно сделать на других языках.

Предположим, у меня есть три вара, и я установил для них одно и то же значение:

MyObject Ob1 = new MyObject(ID:1); 
MyObject Ob2 = Ob1;
MyObject Ob3 = Ob1;

(предположим, что эти вары НЕ находятся в одном контексте, и я просто не могу заменить их одним, и я не могу знать, существуют ли они вообще. Их может быть одна, две или сотни, представляющие один и тот же объект ...)

Я знаю, что изменения, которые я вношу в объект с помощью Ob3, фактически изменяют объекты в Ob1 и Ob2 (конечно, все они представляют один и тот же объект с идентификатором: 1).

Но если я назначу что-то для Ob3, используя Ob3 = new MyObject(ID:2), это не изменит значения Ob1 и Ob2, поскольку они будут продолжать представлять объект с идентификатором: 1.

// What happens:
Ob3 = new MyObject(ID:2);
// Ob3 is no longer the same as Ob1 and Ob2, wich are still the ID:1 object.

Я хочу назначить сразу все три переменные, например, когда я пишу соответствующий код для Ob3 = new MyObject(ID:2);, все другие вары представляют объект с ID: 2, а не ID: 1 больше.

//What I want:
Ob3 = new MyObject(ID:2); //using the suited operators I don't know
//And Ob1 and Ob2 become the ID:2 object as well.

Я знаю, что это можно сделать с помощью указателей в C ++ (очевидно, с некоторыми изменениями в объявлениях и назначениях), но я не хочу управлять вещами на неуправляемом языке. Так есть ли аналогичный способ сделать это "обратное" присваивание в C # ??


person Daniel Möller    schedule 28.02.2013    source источник
comment
если вы собираетесь лечить все одинаково, везде, какой смысл иметь 3 из них? просто используйте Ob1 во всех местах, где используются Ob2 и Ob3, и вы добьетесь того, о чем просите   -  person Sten Petrov    schedule 28.02.2013
comment
^ Это. Я вижу, откуда вы, но переменная - это просто ссылка на местоположение, когда вы меняете свойство вне ссылки, вы меняете то же местоположение. Когда вы изменяете фактическое местоположение, изменяя саму переменную, очевидно, что оно меняет место, куда указывает.   -  person Rudi Visser    schedule 28.02.2013
comment
Стэн, эти вары не в одном контексте.   -  person Daniel Möller    schedule 28.02.2013
comment
Я не думаю, что есть способ сделать это. По сути, у вас есть три «токена» (Ob1, Ob2 и Ob3), которые просто указывают на один и тот же MtObject в памяти. Если вы назначаете новый MyObject одному из этих токенов, то этот токен указывает на этот новый MyObject в памяти. Мне любопытно, почему вы хотите, чтобы три отдельных токена указывали на одно и то же. Все, что вы действительно хотели бы сделать, это сказать Ob1.ID = 2? Поскольку Ob1, Ob2 и Ob3 все указывают на одно и то же, то этот MyObject в памяти изменит свой идентификатор, поэтому эти три будут отражать это.   -  person Tory    schedule 28.02.2013
comment
У меня есть неопределенное количество объектов, содержащих неопределенное количество SubObject в качестве членов. И у меня есть неопределенное количество объектов ReferencerObject, которые должны хранить неопределенное количество этих объектов SubObject. Я хочу воссоздать один из этих SubObject и автоматически реплицировать это изменение во всех ReferencerObject.   -  person Daniel Möller    schedule 28.02.2013


Ответы (3)


Ты можешь это сделать:

MyObject Ob1 = new MyObject(ID:1), Ob2 = Ob1, Ob3 = Ob1;

и все 3 будут указывать на один и тот же объект. Но если вы тогда скажете

Ob3 = new MyObject(ID:2);

Ob1 и Ob2 по-прежнему будут указывать на один и тот же MyObject, а Ob3 будет указывать на новый MyObject. Это потому, что они ссылочные типы, поэтому значение, хранящееся в Ob1, в основном является указателем на сам объект. Вы хотите, чтобы все 3 вещи указывали на одно и то же. Если MyObject обновляется, вы можете сказать что-то вроде

Ob3.Reset(ID:2);

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

Tuple<MyObject> Ob1 = new Tuple<MyObject>(new MyObject(ID:1)), Ob2 = Ob1, Ob3 = Ob1;
Ob3.Item1 = new MyObject(ID:2);

Изменить: я хотел бы уточнить, что я не думаю, что это вообще будет хорошо, это что-то вроде взлома. Может быть несколько случаев, когда это полезно, но держать переменные внутри кортежей обычно не стоит.

person sammy_winter    schedule 28.02.2013

Вы могли сделать это:

MyObject Obj1, Obj2, Obj3 = new MyObject(ID:1);
Obj1 = Obj2 = Obj3 = new MyObject(ID:2);
person David Innes    schedule 28.02.2013

MyObject obj1  //This create a reference variable on the stack
obj1 = new MyObject(ID:1)  //This create a new object of type MyOjbect on the heap and then assigns the memory location of this new object to obj1.

MyObject obj2 //This creates a reference variable on the stack, pointing at nothing
obj2 = obj1   //This assigns the memory location of the object (already created) on the heap to the reference variable on the stack

То же самое и для obj3.

То, что вы хотите сделать так, как вы хотите, невозможно, вам нужно явно указать ссылочным переменным obj1 и obj2, чтобы они указывали на созданный здесь объект:

Ob3 = new MyObject(ID:2);

Поскольку obj1 НЕ является объектом, obj2 НЕ является объектом, obj3 НЕ является объектом. Это ссылка на место в памяти объекта. Итак, если вы скажете obj3 создать новый экземпляр (создать новый объект типа MyObject) в куче, это не имеет абсолютно никакого отношения к тому, где obj1 или obj2 указывают на

Вот картинка, чтобы помочь в понимании

введите описание изображения здесь

Ссылочные переменные содержат шестнадцатеричный номер области памяти, в которой находится объект в куче. Поэтому, когда вы назначаете одну ссылочную переменную другой, вы фактически просто копируете шестнадцатеричное число из одного в другое, и это шестнадцатеричное число представляет ГДЕ живет объект

person Steve's a D    schedule 28.02.2013
comment
@ Дэниел, уточни. Ссылочные переменные - это то же самое, что и указатель, за исключением того, что он предназначен только для объектов (своего рода). В C ++ вы не работаете напрямую с объектами, вы работаете с указателями, которые указывают на объекты - очень похоже на ссылки - person Steve's a D; 28.02.2013
comment
В C ++ я могу использовать (* Pointer) = value; и, таким образом, все указатели на этот объект будут указывать на это новое значение. (это именно то, что я хочу сделать, но в C #, управляемом языке); - person Daniel Möller; 28.02.2013
comment
*Pointer - это С ++ говорит то, на что я указываю. Если вы cout &Pointer, он распечатает шестнадцатеричную ячейку памяти, в которой находится объект. Вы не работаете напрямую с объектами - person Steve's a D; 28.02.2013
comment
Я понимаю. Я понимаю указатели, мне просто интересно, есть ли что-то похожее на то, на что я указываю в C #. - person Daniel Möller; 28.02.2013
comment
@Daniel ахх, это автоматически, вам действительно нужно использовать другую функцию, чтобы иметь возможность вытащить шестнадцатеричное число из переменной ref - person Steve's a D; 28.02.2013