学习一下C#的深拷贝

以前一直在写C++,最近玩起了C#,才发现C#的深拷贝好麻烦。

问题

我在程序的一个类Class1里新建了一个List,用于存放另一个类Class2的实例,而Class2中另有一个List。然后某些操作需要将其中一个Class1实例的数据拷贝到另一个实例当中。我本以为用类似C++的vector的拷贝方法就可以:

a.list = new List<Class2>(b.list);

结果我在改变b.list当中的List内某个元素的值时,发现a.list里面对应元素的值也改变了。原因是以上方法只是浅拷贝,只拷贝了引用。

解释

C#里有两种数据类型,一种是值类型,如int等基础类型,而同时struct也是直接值传递的;一种是引用类型,如自定义的类,包括string其实也是引用类型,只不过内部做了一些处理。当然,struct里面有引用类型的话,这些引用类型还是只传了引用。new List<Class>(list)也只不过是将list里的每个元素的引用传给了新的List,因此改变其中一个必然导致另外一个改变。

深拷贝

网上有许多深拷贝的方法,什么序列化、反射等等,暂时还看不懂。倒是有一个方法比较简便,就是自定义的类继承ICloneable这个基类,然后在类内部实现public object Clone()方法。类结构大致如下:

class Class2 : ICloneable
{
    List<int> list;
    ...
    public object Clone()
    {
        Class2 newObject = new Class2();  //新建一个实例
        newObject.list = new List<int>(list);
        return newObject;
    }
}

以上代码里Class2的list里是值类型,可以直接用new List<int>(list)来拷贝。到了Class1里,情况就不一样了:

class Class1 : ICloneable
{
    List<Class2> list;
    ...
    public object Clone()
    {
        Class1 newObject = new Class1();  //新建一个实例
        newObject.list = new List<int>();  //初始化一个List
        //将本实例的list每个元素都深拷贝一份到新实例的list内
        list.Foreach(i => newObject.list.Add(i.Clone()));
        return newObject;
    }
}

这样就可以完成深拷贝。拷贝构造函数里面还是继续用浅拷贝,而需要深拷贝时调用Clone()函数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值