2014-06-19 241 views
0

我有这样一个类:创建一个新的类实例

Public Class Dog{ 
    public Dog(string name, int age){ 
     Name = name; 
     Age = age; 
    } 

    public string Name { get; set; } 
    public int Age { get; set; } 
} 

然后,我创建这个类

Dog jake = new Dog("Jake", 3); 

的一个实例,当我试图复制类和改变像

Dog buster = jake; 
buster.Name = "Buster"; 

它的属性我这样做的时候,杰克的名称将改变过

我该如何避免这种情况?

请注意,我正在使用的类包含如此多的属性,如果我可以复制类并更改我想要的一个属性,它将使我更容易。

+7

看到这里http://stackoverflow.com/questions/78536/deep-cloning-objects。现在,您只是将*引用*复制到对象,这就是为什么更改该对象的属性同时改变两个对象的原因。他们指的是同一个对象。 –

+0

在C++中拷贝一个变量。不在C#http://www.albahari.com/valuevsreftypes.aspx –

回答

5

这会发生,因为内存在C#中的工作方式。每个类对象实际上都是一个指向内存中的对象的指针 - 当您将一个变量分配给另一个变量时,您仍然使用相同的指针,并因此在对一个对象进行更改时修改相同的数据。从技术上讲,如果你制作了所有的对象结构体,它们就会很好地复制,因为结构体是值类型,因此可以传递副本。然而,这是非常不明智的,因为它限制了用法,特别是对于多态性,并且对于具有许多成员的对象的内存管理来说是一个坏主意。

解决此问题的最佳方法是在类Dog上实现一个函数,该函数允许您将数据复制到新的Dog对象中。因此,您可以拨打

Dog buster = jake.Clone(); 
buster.Name = "Buster"; 

并在克隆中,将当前Dog对象的所有属性复制到新的Dog对象中。

编辑:回到C++根,实现一个“复制构造函数”,它采用相同类型的参数并进行深度复制也很常见。 IE

Dog jake = new Dog() { Name = "Jake" }; 
Dog buster = new Dog(jake) { Name = "Buster" }; 

注:上述语法使用大括号,它允许您在创建类时立即设置类中的属性和字段。虽然技术上编译器糖,它非常善于使实例化调用更简洁

0

当你做狗巴士=杰克。你创建一个指向jake的变量

所以,当你做buster.name = buster时,你在技术上会改变jakes的名字。

+0

我忽略了另一行。 – MGHandy

相关问题