从C#中的MemberwiseClone()浅拷贝说起
MemberwiseClone() 是 C# 中的一个方法,用于创建当前对象的浅拷贝(shallow copy)。它属于 System.Object 类,因此所有 C# 对象都可以调用该方法。
1. MemberwiseClone() 的含义
浅拷贝:MemberwiseClone() 会创建一个新对象,并将当前对象的所有字段复制到新对象中。对于值类型字段,直接复制值;对于引用类型字段,复制的是引用(即新对象和原对象共享相同的引用类型实例)。
返回类型:返回一个 object 类型,因此通常需要将其强制转换为目标类型。
2. 示例代码
public class Person
{
public string Name;
public int Age;
public Address Address;
public Person ShallowCopy()
{
return (Person)this.MemberwiseClone();
}
}
public class Address
{
public string City;
public string Street;
}
class Program
{
static void Main()
{
Person person1 = new Person
{
Name = "John",
Age = 30,
Address = new Address { City = "New York", Street = "5th Avenue" }
};
Person person2 = person1.ShallowCopy();
Console.WriteLine(person1.Address.City); // 输出: New York
Console.WriteLine(person2.Address.City); // 输出: New York
person2.Address.City = "Los Angeles";
Console.WriteLine(person1.Address.City); // 输出: Los Angeles
Console.WriteLine(person2.Address.City); // 输出: Los Angeles
}
}
在上面的例子中,person2 是 person1 的浅拷贝。修改 person2 的 Address 属性会同时影响 person1,因为它们共享同一个 Address 对象。
3. 其他相关函数
深拷贝(Deep Copy):与浅拷贝不同,深拷贝会递归复制所有引用类型字段,创建一个完全独立的对象。C# 没有内置的深拷贝方法,通常需要手动实现或使用序列化等方式。
示例实现深拷贝:
public class Person
{
public string Name;
public int Age;
public Address Address;
public Person DeepCopy()
{
Person other = (Person)this.MemberwiseClone();
other.Address = new Address { City = this.Address.City, Street = this.Address.Street };
return other;
}
}
ICloneable 接口:这是一个标准接口,定义了 Clone() 方法,用于支持对象的克隆。可以实现该接口来提供自定义的克隆逻辑。
示例:
public class Person : ICloneable
{
public string Name;
public int Age;
public Address Address;
public object Clone()
{
return this.MemberwiseClone(); // 浅拷贝
}
}
序列化实现深拷贝:通过序列化和反序列化实现深拷贝。
示例:
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class ObjectCopier
{
public static T DeepCopy<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T)formatter.Deserialize(ms);
}
}
}
4. 应用场景
浅拷贝:适用于对象结构简单,且引用类型字段不需要独立拷贝的场景。
深拷贝:适用于对象结构复杂,且需要完全独立拷贝的场景,例如在需要修改拷贝对象而不影响原对象时。
总结
MemberwiseClone() 是 C# 中用于浅拷贝的方法。
深拷贝需要手动实现或通过序列化等方式实现。
ICloneable 接口提供了一种标准化的克隆方式。