65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 对象克隆机制

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.27/5 (8投票s)

2009年3月19日

CPOL

2分钟阅读

viewsIcon

22390

downloadIcon

422

一个克隆你的 C# 类的类。

引言

在大多数情况下,无论你参与软件开发的哪个领域,你都需要克隆对象的功能。.NET Framework 提供了三种实现对象复制目标的方法

  1. 实现 ICloneable 接口,并为涉及的每个类手动开发克隆功能。
  2. 将对象序列化到二进制流,并使用 BinaryFormatterMemoryStream 类对其进行反序列化。在这种情况下,你的类需要是可序列化的。
  3. 使用反射进行克隆。

有时,当你在大型项目上工作时,“愚蠢的”深度复制是不够的。假设在某些情况下,你需要包含子对象,而在其他情况下,不需要。例如,让我们考虑这些类

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 类时,从克隆中排除 ManagerFriends 对象。但是,当使用“Friends”风格([Cloneable(CloneableState.Include, "Friends")])克隆时,也复制 Person 的朋友。使用这个机制非常简单。示例

ObjectCloner.Clone(person);
ObjectCloner.Clone(person, "Friends");

因此,在前面的示例中的第一个语句仅复制 FirstnameLastname。第二个语句执行深度复制并克隆了该人的朋友。

这是基于前面描述的示例的演示应用程序的输出。

binary_CSharp_Object_Cloner

在这里,你可以看到“De Niro”的两个副本都没有定义管理器,并且在使用“Friends”风格克隆时,该机制通过填充该人的朋友来执行深度复制。

Origin

本文的原始出处可以在 C# 对象克隆机制 找到。

© . All rights reserved.