我前几天使用自定义方法深度克隆对象,我知道你可以用不同的方式深度克隆(反射,二进制序列化等),所以我只是想知道:
微软在框架中不包含深层复制方法的原因是什么?
问题比你想象的要困难得多,至少在一般情况下如此.
对于初学者来说,副本不仅是深度还是浅薄,而是一个频谱.
让我们想象一下,我们有一个字符串数组列表,我们想要复制它.
我们从最浅层开始,我们只是将整个事物的引用复制到另一个变量.对另一个变量引用的列表的任何更改都会被另一个变量看到.
所以现在我们去创建一个全新的列表来给第二个变量.对于第一个列表中的每个项目,我们将其添加到第二个列表中.现在我们可以修改从任一变量引用的列表,而不会被另一个变量看到.但是如果我们抓住列表的第一项并更改第一个数组中的字符串,那么两个列表都会看到它!
现在我们正在创建一个新列表,对于第一个列表中的每个数组,我们创建一个新数组,将基础数组中的每个字符串添加到新数组中,并将每个新数组添加到新的清单.现在我们可以改变任一列表中的任何数组而不会看到更改.但是等等,两个列表仍然引用相同的字符串(毕竟它们是值类型;它们内部有一个字符数组用于它们的数据).如果一些卑鄙的人出现并改变其中一个字符串(使用不安全的代码,你实际上可以这样做)会怎么样?所以现在你要用深拷贝复制所有字符串.但是,如果我们不需要那样做呢?如果我们知道没有人会这么说他们会改变字符串怎么办?或者,就此而言,如果我们知道没有任何数组将被突变(或者如果它们将被突变,那么它们应该被两个列表反映出来).
然后当然存在诸如循环引用之类的问题,类中的字段实际上并不代表它的状态(即可能根据克隆需要重新计算的缓存值或派生数据).
实际上你需要拥有每个类型的工具IClonable或一些等价物,并拥有自己的自定义代码来克隆自己.这对于维护语言来说需要做很多工作,特别是因为有很多方法可以克隆复杂的对象.成本会非常高,并且(在少数几个被认为值得实现克隆方法的对象之外)的好处通常是不值得的.作为程序员,您可以根据自己知道的深度来编写自己的逻辑来克隆类型.
它类似于在C和C ++中的工作方式(或不工作):
要进行深层复制,您实际上必须知道如何解释不同的数据。在平凡的情况下,提供的浅表副本与深表副本相同。但是,一旦这不再成立,它实际上取决于实现和解释。没有一般的经验法则。
让我们以一个游戏为例:
我可以想到两种可能的解决方案:
UniqueID一定不要复制,但是同时您不能定义应该如何进行。即使可以,您也可以...CopyTo())。