C# 对象克隆机制






4.27/5 (8投票s)
一个克隆你的 C# 类的类。
引言
在大多数情况下,无论你参与软件开发的哪个领域,你都需要克隆对象的功能。.NET Framework 提供了三种实现对象复制目标的方法
- 实现
ICloneable
接口,并为涉及的每个类手动开发克隆功能。 - 将对象序列化到二进制流,并使用
BinaryFormatter
和MemoryStream
类对其进行反序列化。在这种情况下,你的类需要是可序列化的。 - 使用反射进行克隆。
有时,当你在大型项目上工作时,“愚蠢的”深度复制是不够的。假设在某些情况下,你需要包含子对象,而在其他情况下,不需要。例如,让我们考虑这些类
public class Person
{
private List<Person> _friends = new List<Person>();
public string Firstname { get; set; }
public string Lastname { get; set; }
public List<Person> Friends { get { return _friends; } }
public PersonManager Manager { get; set; }
}
public class PersonManager
{
private List<Person> _persons = new List<Person>();
public List<Person> Persons
{
get { return _persons; }
}
}
在某些情况下,当复制单个 Person
时,不需要复制 PersonManager
。在其他情况下,你希望将 Person
的朋友包含在克隆中,再次,在其他情况下,不需要。正如你已经注意到的,在这个简单的例子中,情况太多了。在实际情况下,它们会更加复杂。
使用代码
我建议使用声明式的方式来定义克隆逻辑。考虑对我们的 Person
类进行以下修改
public class Person
{
private List<Person> _friends = new List<Person>();
public string Firstname { get; set; }
public string Lastname { get; set; }
[Cloneable(CloneableState.Exclude)]
[Cloneable(CloneableState.Include, "Friends")]
public List<Person> Friends { get { return _friends; } }
[Cloneable(CloneableState.Exclude)]
public PersonManager Manager { get; set; }
}
它表示,在克隆 Person
类时,从克隆中排除 Manager
和 Friends
对象。但是,当使用“Friends”风格([Cloneable(CloneableState.Include, "Friends")]
)克隆时,也复制 Person
的朋友。使用这个机制非常简单。示例
ObjectCloner.Clone(person);
ObjectCloner.Clone(person, "Friends");
因此,在前面的示例中的第一个语句仅复制 Firstname
和 Lastname
。第二个语句执行深度复制并克隆了该人的朋友。
这是基于前面描述的示例的演示应用程序的输出。
在这里,你可以看到“De Niro”的两个副本都没有定义管理器,并且在使用“Friends”风格克隆时,该机制通过填充该人的朋友来执行深度复制。
Origin
本文的原始出处可以在 C# 对象克隆机制 找到。