最近碰到了一个比较复杂的类的复制问题。
.net中对于所有的类都有一个继承object得来的MemberwiseClone方法。MemberwiseClone方法提供了类的浅复制。为什么说是浅复制呢?使用MemberwiseClone方法进行复制时,对于类中的值类型会创建新的变量,而对于引用变量来说,会指向原来的引用并不创建新的引用变量,详细介绍可参见以下链接。
http://msdn.microsoft.com/zh-cn/library/system.object.memberwiseclone.aspx
msdn上给出了一个简单包含引用类型的类实现深层复制的方法,但是如果类中含有list属性的话,list本身是引用类型,“=”符号不会产生该list的副本只是复制了引用,所以需要用迭代来复制整个list。用代码对深层复制大概进行一下总结:
class Program
{
static void Main(string[] args)
{
School school1 = new School();
//调用School的Clone方法创建深层副本
School school2 = (School)school1.Clone();
//修改school1的属性,看是否会对school2造成影响
school1.President.Name = "刘某";
school1.Grades[0].ID = 3;
school1.Buildings[0] = "3楼";
Console.ReadLine();
}
}
public class School : ICloneable
{
public string City { get; set; }
public string Name { get; set; }
public President President { get; set; }
public List<Grade> Grades { get; set; }
public List<string> Buildings { get; set; }
/// <summary>
/// Initialize School
/// </summary>
public School()
{
City = "A市";
Name = "A市一中";
President = new President
{
Age=50,
Name ="张某"
};
Grades = new List<Grade>();
Grades.Add(new Grade{ID=1, Name="一年级"});
Grades.Add(new Grade{ID=2, Name="二年级"});
Buildings = new List<string>();
Buildings.Add("1楼");
Buildings.Add("2楼");
}
/// <summary>
/// Deep Copy School
/// </summary>
/// <returns>Deep Copy</returns>
public object Clone()
{
//浅复制一个副本
School newschool = (School)this.MemberwiseClone();
//调用President的Clone方法,为President创建一个新的对象
newschool.President = (President)this.President.Clone();
//清空两个list
newschool.Grades = new List<Grade>();
newschool.Buildings = new List<string>();
//将Grades添加到新的school里
foreach (var grade in Grades)
{
newschool.Grades.Add((Grade)grade.Clone());//通过调用Grade的Clone方法进行复制
}
//将Buildings添加到新的school里
foreach (var building in Buildings)
{
newschool.Buildings.Add(building);
//string类型虽然是引用类型,但是在.net框架里面,“=”符号是创建一个新的string对象存在堆里,所以不用clone方法也可以实现string的复制
//newschool.Buildings.Add((string)building.Clone());
}
return newschool;
}
}
public class Grade : ICloneable
{
public int ID { get; set; }
public string Name { get; set; }
public object Clone()
{
return this.MemberwiseClone();
}
}
public class President : ICloneable
{
public int Age { get; set; }
public string Name { get; set; }
public object Clone()
{
return this.MemberwiseClone();
}
}
public class Person : IComparable
{
public string FirstName;
public string LastName;
public Person()
{ }
public Person(string first, string last)
{
FirstName = first;
LastName = last;
}
public int CompareTo(object obj)
{
Person other = obj as Person;
int result = this.LastName.CompareTo(other.LastName);
this.MemberwiseClone();
return result;
}
}
以上是深层复制大概的使用方法,用这种方法实现以后发现网上有牛人有更简单的方法,不用实现ICloneable接口的Clone方法,使用序列化解决了这个问题。大家可以参考一下下面这个资料。
http://www.cnblogs.com/zhangji/archive/2011/02/23/1961897.html