C# 对象的深度复制
我有两节课。在一个类中嵌套了另一个类C# 对象的深度复制,c#,deep-copy,shallow-copy,C#,Deep Copy,Shallow Copy,我有两节课。在一个类中嵌套了另一个类 class Person : ICloneable { public string name; public City city; public object Clone() { return this.MemberwiseClone(); } } class City { public string name; public City( string _n) {
class Person : ICloneable
{
public string name;
public City city;
public object Clone()
{
return this.MemberwiseClone();
}
}
class City
{
public string name;
public City( string _n)
{
name = _n;
}
}
在Person类中,使用克隆方法进行浅层复制。
当我制作类人克隆时,我得到了类人克隆和嵌套类城市克隆
Person person = new Person()
{
name = "John",
city = new City("London")
};
Person personNew = (Person)person.Clone();
Console.WriteLine( $"{personNew.name}\t\n{personNew.city.name}");
Result:
John
London
我希望City类的值为null,因为我制作了Person类的浅拷贝,但它看起来像深拷贝。为什么? 不,它不是DeepCopy,要了解发生了什么,请尝试在您的代码之后添加此代码
personNew.name = "Steve";
personNew.city.name = "Paris";
// Print out the values of the original person
Console.WriteLine($"{person.name}\t\n{person.city.name}");
结果:
John
Paris
因此,您更改了newPerson中的城市名称,但这也会影响到该城市。发生这种情况是因为它们是City类的同一个实例。这就是MemberwiseClone所做的。它复制字段值,但不创建新对象实例。对于引用类型,字段值是对对象实例的引用,而不是实例本身
如果要执行DeepCopy,首先需要将[Serializable]属性添加到类中
[Serializable]
class Person
....
[Serializable]
class City
然后将克隆方法更改为
public object Clone()
{
using (MemoryStream stream = new MemoryStream())
{
if (this.GetType().IsSerializable)
{
BinaryFormatter fmt = new BinaryFormatter();
fmt.Serialize(stream, this);
stream.Position = 0;
return fmt.Deserialize(stream);
}
return null;
}
}
您可以在下面的答案中找到一个更好的DeepCopy方法示例:
您刚刚用浅拷贝进行了拷贝,这是正确的。 当然,它会复制
person
实例的所有属性。为什么你认为城市是一个例外而不被复制?
如果要执行深度复制,请尝试以下操作:
个人班级:
class Person : ICloneable
{
public string name;
public City city;
public object Clone()
{
return this.MemberwiseClone();
}
public Person DeepCopyAndDisposeCity()
{
return new Person()
{
name = this.name,
city = null
};
}
}
节目:
Person person = new Person()
{
name = "John",
city = new City("London")
};
Person personNew = person.DeepCopyAndDisposeCity(); //(Person)person.Clone();
//personNew.city = new City( "Hanoi");
string cityOfNewPersion= personNew.city == null ? "null" : personNew.city.name;
Console.WriteLine("Person:");
Console.WriteLine($"{person.name}\t\n{person.city.name}");
Console.WriteLine("New Person:");
Console.WriteLine($"{personNew.name}\t\n{cityOfNewPersion}");
Console.ReadKey();
仍然有一个
City
对象,您的Person
对象都引用了同一个对象。深度克隆将导致城市
对象也被复制。