📅  最后修改于: 2023-12-03 15:29:47.114000             🧑  作者: Mango
在 C# 中,我们可以使用两种方法来复制对象:浅复制和深复制。
浅复制是指复制对象时只复制其成员变量的值,而不是复制其引用类型变量所引用的对象。换言之,浅复制会复制引用类型变量的地址,这样两个对象会引用相同的对象,只是使用的变量名不同。
我们可以通过重载对象的 Clone()
方法来实现浅复制。以下是一个示例:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Address Address { get; set; }
public Person Clone()
{
return (Person)this.MemberwiseClone();
}
}
class Address
{
public string City { get; set; }
public string State { get; set; }
}
// 测试代码
Person a = new Person() { Name = "Alice", Age = 20, Address = new Address() { City = "New York", State = "NY" } };
Person b = a.Clone();
Console.WriteLine($"a: {a.Name} ({a.Age}), {a.Address.City}, {a.Address.State}");
Console.WriteLine($"b: {b.Name} ({b.Age}), {b.Address.City}, {b.Address.State}");
a.Name = "Bob";
a.Age = 30;
a.Address.City = "Seattle";
a.Address.State = "WA";
Console.WriteLine($"a: {a.Name} ({a.Age}), {a.Address.City}, {a.Address.State}");
Console.WriteLine($"b: {b.Name} ({b.Age}), {b.Address.City}, {b.Address.State}");
输出结果:
a: Alice (20), New York, NY
b: Alice (20), New York, NY
a: Bob (30), Seattle, WA
b: Alice (20), Seattle, WA
可以发现,虽然 a
和 b
最初的值是相同的,但是当我们修改 a
的属性时,b
并未跟着变化,因为它们引用的是不同的 Address
对象。
需要注意的是,Clone()
方法默认是浅复制,因此如果对象中包含引用类型的成员变量,则需要在 Clone()
方法中对其进行深复制。
深复制是指复制对象时不仅复制其成员变量的值,还会复制其引用类型变量所引用的对象。这样,两个对象引用的是不同的对象,修改其中一个对象不会影响另一个对象。
实现深复制有多种方法,其中一个简单的方法是将对象序列化为字节数组,然后再反序列化得到一个新的对象。以下是一个示例:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Address Address { get; set; }
public Person DeepClone()
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
return (Person)formatter.Deserialize(stream);
}
}
}
class Address
{
public string City { get; set; }
public string State { get; set; }
}
// 测试代码
Person a = new Person() { Name = "Alice", Age = 20, Address = new Address() { City = "New York", State = "NY" } };
Person b = a.DeepClone();
Console.WriteLine($"a: {a.Name} ({a.Age}), {a.Address.City}, {a.Address.State}");
Console.WriteLine($"b: {b.Name} ({b.Age}), {b.Address.City}, {b.Address.State}");
a.Name = "Bob";
a.Age = 30;
a.Address.City = "Seattle";
a.Address.State = "WA";
Console.WriteLine($"a: {a.Name} ({a.Age}), {a.Address.City}, {a.Address.State}");
Console.WriteLine($"b: {b.Name} ({b.Age}), {b.Address.City}, {b.Address.State}");
输出结果:
a: Alice (20), New York, NY
b: Alice (20), New York, NY
a: Bob (30), Seattle, WA
b: Alice (20), New York, NY
可以发现,b
的值没有跟着变化,这是因为 a.DeepClone()
创建了一个新的对象,与 a
没有关系。
需要注意的是,在实现 DeepClone()
方法时,需要保证对象及其成员变量是可序列化的。