奇怪的价值参考

时间:2011-11-16 07:59:42

标签: c# instantiation

我今天遇到了一个问题,这个问题在我之前曾多次发生过。我有一个我的对象的通用列表:

List<Classes.Object.GameObject> ObjectList = new List<Classes.Object.GameObject>();

我决定从列表中获取Classes.Object.GameObject的实例:

Classes.Object.GameObject TempObject = new Classes.Object.GameObject;
TempObject = ObjectList[10];

直到这里工作得很好但是当我对TempObject进行一些更改时,我提到的列表中的索引对象也发生了变化!我的意思是ObjectList [10]将通过改变TempObject来改变。根本没有参考。也许我没有理解OO编程。

亲爱的主持人你在编辑我的语法时犯了错误! (你改到了直到)

7 个答案:

答案 0 :(得分:2)

在C#中,所有对象都通过 references 处理。问题出在这里:

// Create a new GameObject and have the TempObject reference point to it.
Classes.Object.GameObject TempObject = new Classes.Object.GameObject;
// Change the TempObject reference to point to the object at ObjectList[10].
TempObject = ObjectList[10];

TempObject现在引用列表中的对象。如果更改它,您将更改列表中的对象 - 因为它们是同一个对象。在C#中,如果需要单独的对象,则必须从旧对象中显式创建新对象。如果浅拷贝就足够了,您可以使用MemberWiseClone方法创建一个新对象。

如果你来自C ++,这是一个常见的陷阱;在C ++中,这会将ObjectList[10]处的对象复制到TempObject

答案 1 :(得分:1)

因为您要为GameObject分配TempObject的引用。 ObjectList[10]TempObject引用变量都引用了common对象。

答案 2 :(得分:1)

如果您想更改TempObject而不影响列表中的“原始版本”,请执行复制。在Cloning objects in C#中描述。

答案 3 :(得分:0)

在这种情况下,请确保在不希望引用对象的情况下创建对象的深层副本。

使用此链接获取更多信息Deep Copy in C#

答案 4 :(得分:0)

对于每个引用类型(假设每个“类”),您只能使用“=”设置对变量的引用 想象一下您的列表作为参考列表。 将ObjectList [10]分配给TempObject时,您将引用与ObjectList引用相同的实际对象。

如果要复制对象,请自己创建一个Copy()方法。

答案 5 :(得分:0)

如何将Classes.Object.GameObject定义为值类型(struct)而不是引用类型(class)?你能展示GameObject的定义吗?

答案 6 :(得分:0)

TempObjectObjectList[10]都指向堆中的相同内存位置,因为它们是类的对象,因此也是引用类型。因此,如果您更改一个对象变量中的值,它也会反映在其他变量中,这也是由于在一个内存位置所做的更改。

您可以在下面的文章中很好地掌握值和引用类型中的内存分配:

http://www.albahari.com/valuevsreftypes.aspx