如何在不影响原始对象的情况下为复制对象赋值

时间:2018-01-22 06:52:54

标签: c# class oop object

我创建了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"
}

2 个答案:

答案 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引用,都在修改同一个对象。