0

我不确定我想在 C# 中执行的操作称为什么,但我知道它可以在其他语言中完成。

假设我有三个变量并将它们设置为相同的值:

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

(假设这些变量不在同一个上下文中,我不能用它们代替一个,我也不知道它们是否存在。它们可以是一个、两个或数百个代表同一个对象......)

我知道我通过 对对象所做的Ob3更改实际上会更改其中的对象(当然Ob1Ob2它们都表示具有 ID:1 的同一个对象)。

Ob3但是,如果我使用为 分配一些东西Ob3 = new MyObject(ID:2),这不会改变 和 的值Ob1Ob2因为它们将继续表示 ID: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# 中进行“向后”分配?

4

3 回答 3

1

你可以这样做:

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

编辑:我想证明我认为这通常不是一件好事,它有点像黑客。可能在少数情况下它很有用,但是将变量保存在元组中通常不是什么事情。

于 2013-02-28T19:42:12.393 回答
1
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 指向的位置无关

这是一张有助于理解的图片

在此处输入图像描述

引用变量保存对象在堆上的内存位置的十六进制数。因此,当您将一个引用变量分配给另一个引用变量时,您实际上只是将一个十六进制数字从一个复制到另一个,这个十六进制数字代表对象所在的位置

于 2013-02-28T19:30:38.577 回答
1

你可以这样做:

MyObject Obj1, Obj2, Obj3 = new MyObject(ID:1);
Obj1 = Obj2 = Obj3 = new MyObject(ID:2);
于 2013-02-28T19:30:54.663 回答