c# 浅层复制与深层复制

最近碰到了一个比较复杂的类的复制问题。

.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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值