我创建了3个对象但是当我在3个对象中更改一个对象属性时,所有这些对象都被更改了。 那么如何在不影响其他对象的情况下更改对象属性呢?
public DetachForm(MessageViewModel messageViewModel)
{
a = new MessageViewModel();
a = messageViewModel;
var b = new MessageModel();
b = a.CurrentMessage;
//property name in messageViewModel,a and b object equal to "Old"
b.Name = "New";
//property name in messageViewModel,a and b object equal to "New"
}
答案 0 :(得分:2)
我认为你应该密切关注实际发生的事情。
public DetachForm(MessageViewModel messageViewModel) // <--- first object in memory
{
a = new MessageViewModel(); // <--- create a new object in memory
a = messageViewModel; // <--- change the reference a to reference the messageViewModel
var b = new MessageViewModel(); // <--- create a new third object in memory
b = a; // <--- change b to reference the same object as a
a.id=1; // At this point messageViewModel, a, b - all reference the same object in memory
}
因此,当你到达a.id = 1
行时,你实际上改变了内存中的所有这三个引用所引用的对象。
一旦你执行了函数的第二行,那么你刚刚创建的对象没有引用它的引用,GC将收集该内存。同样适用于第四行功能。
要更改b
的属性而不更改messageViewMovel
(因为这些是引用类型,无论如何您要创建新实例):
var b = new MessageViewModel();
b.id = 1; // when debugging see that messageViewModel was not changed
即使在您的更新中,您也遇到了同样的问题。以下代码与您在更新中编写的内容相同:
a = messageViewModel;
var b = a.CurrentMessage;
b.Name = "New";
因此,如果您认为创建新实例并不重要,那么您可以使用&#34; old&#34;来覆盖它们。一。因此,当您更改b.Name
时,您实际访问的内存中的同一对象为a.CurrentMessage.Name
。
如果您要复制所有MessageViewModel
,我建议您查看IClonable
(或拥有复制构造函数)。如果您的类将实现该接口,那么您可以:
var copy = messageViewModel.Clone();
copy.CurrentMessage.Name = "something"; // original will not change
答案 1 :(得分:0)
此行为来自C#处理对象引用的方式。当你这样做时:
b = a;
你说 b 应该引用与 a 相同的对象。无论是否使用a或b引用,都在修改同一个对象。