【问题标题】:Changing the property of A object affects the changing the property of B object更改 A 对象的属性会影响更改 B 对象的属性
【发布时间】:2013-07-21 19:32:14
【问题描述】:

我有这行代码:

SomeClass a = new SomeClass();
SomeClass b = a;
a.price = 15;
b.price = 20;

Console.WriteLine(a.price); // output 20

首先我创建对象 a,然后创建对象 b。我为对象 b 分配了对象 a。当我为这些对象初始化属性价格时,您可以看到对象 a 的价格为 15,b 的价格为 20。但是当您将 20 分配给对象 b 的价格时,同时更改会影响对象 a 的价格。 为什么?

我的意思是内存中发生了什么导致这种情况?

【问题讨论】:

  • object b 是对 object a 的引用,如果您知道指针,则为指针,因此如果 a 或 b 发生变化,则另一个反映了变化
  • @MEYWD: b 根本不是一个对象。这是一个变量b 的值与a 的值相同——两者都是对同一个对象的引用。区分变量、引用和对象的概念非常重要。更改a 的值(以引用不同的对象)不会b 的值做任何事情。这只是反映了他们两个引用的对象的更改。
  • @JonSkeet 你是对的,我只是想用一种简单的形式来解释它,我所说的对象是指变量。
  • @MEYWD:问题在于,让事情变得“简单”往往会使事情变得混乱:(

标签: c# object memory-management


【解决方案1】:

SomeClass 是一个引用类型(用类SomeClass { ... } 声明)。 ab 引用了类的同一个实例(您使用 new SomeClass() 创建的实例。这意味着,它指向同一个实例(然后指向同一个内存项)。

要获得您想要的行为,您必须使用值类型(使用 struct SomeStruct { ... } 声明)。

【讨论】:

  • 是的,当我用 struct 更改 class 时,这不会发生。谢谢。
  • 但是,要小心结构。因为执行b = a 会将a 的内存复制到b(即使调用以a 作为参数的方法也会复制它)。所以,不要创建大结构。见Using structs
  • 好的。谢谢你的建议。 :-)
【解决方案2】:

这是ValueTypeReferenceType 之间的基本区别。

使用 ValueType 在内存中分配一个空间来存储值。(例如:int、bool、char 是值类型)。

使用 ReferenceType 在内存中创建一个对象,然后通过一个单独的引用进行处理——就像一个指针。这个引用负责改变前一个对象的值。 More here

【讨论】: