まず、深い浅いコピーのコピーは何ですか
すべてのオブジェクト指向言語では、コピーは常に議論のトピックにつながるしやすくなり、C#も例外ではありません。このような質問は、非常に簡単ですインタビューで尋ねた私たちは深いと浅いコピーは、設計の観点から、オブジェクトのコピーをサポートする方法の更なる検討に基づいて基本的な概念をコピーし理解する必要があります。
System.Objectのクラス、保護方法object.MemberwiseClone()で、この方法の実装レプリケーションオブジェクト。実際には、それは我々が浅いコピーを呼んで実現しました。
いわゆるシャローコピー元のオブジェクトの場合、非静的メンバの値型と参照型へのすべての参照のコピーがすべてのメンバーオブジェクトのコピーを意味します。換言すれば、新しいオブジェクトと元のオブジェクトは、実際のオブジェクト参照型のすべてのメンバーによって共有されます。相対は、ディープコピーは、非静的メンバの値型のすべてをコピーするだけでなく、意味だけでなく、すべての実際のオブジェクト参照型メンバをコピーします。深いコピーと浅いコピーの概念は、参照型のメンバーが別のメンバーが、コピーはその内部のメンバーをコピーするのと同じ戦略を実装する参照型が含まれている場合である、再帰的です。
浅いコピーモードを以下に示します。
下に示したディープコピー概略図:
すべてのタイプが既に浅いコピー、タイプを達成し、このインタフェースが実現ICloneableインターフェイスによって実装されるインタフェースのコピー、および通常は開いているしなければならないしているのSystem.Objectの基本クラスを入力します。ICLoneableはCloneメソッドが含まれています。浅いコピーが特定のニーズに応じて種類の特定のニーズを選択する方法、ディープコピーとして実装することができるの方法のいずれかで実装されてもよいです。次のコードのディープコピーの簡単な例を提供します。
using System; namespace DeepCopy { class Program { static void Main(string[] args) { // 定义原始对象 DpCopy dc = new DpCopy(); dc._i = 10; dc._a = new A(); // 定义深拷贝对象 DpCopy deepClone = (DpCopy)dc.Clone(); // 定义浅拷贝对象 DpCopy shadowclone = (DpCopy)dc.MemberwiseClone(); // 深拷贝的复制对象将拥有自己的引用类型成员对象 // 所以这里的赋值不会影响原始对象 deepClone._a._s = "我是深拷贝的A"; Console.WriteLine(dc); Console.WriteLine(deepClone); Console.WriteLine("\r\n"); // 浅拷贝的复制对象共享原始对象的引用类型成员对象 // 所以这里的赋值将影响原始对象 shadowclone._a._s = "我是浅拷贝的A"; Console.WriteLine(dc); Console.WriteLine(shadowclone); Console.ReadKey(); } } public class DpCopy : ICloneable { public int _i = 0; public A _a = new A(); public object Clone() { // 实现深拷贝 DpCopy newDc = new DpCopy(); // 重新实例化一个引用类型变量 newDc._a = new A(); // 给新引用类型变量的成员值 newDc._a._s = _a._s; newDc._i = _i; return newDc; } // 实现浅拷贝 public new object MemberwiseClone() { return base.MemberwiseClone(); } /// <summary> /// 重写类的ToString()方法 /// </summary> /// <returns></returns> public override string ToString() { return "I的值为:" + _i.ToString() + ",A为:" + _a._s; } } /// <summary> /// 包含一个引用成员的类型 /// </summary> public class A { public string _s = "我是原始A"; } }
在上面的代码中,类型DpCopy通过ICLoneable接口的Clone方法提供了深拷贝,并且通过提供一个MemberwiseClone的公共方法提供了浅拷贝。DpCopy类型具有一个值类型成员和一个引用类型成员,引用类型成员在浅拷贝和深拷贝时将展现不同的特性,浅拷贝的原始对象和目标对象公用了一个引用类型成员对象,这在程序的执行结果中可以清楚地看到:
有的参考资料上说C#中的深拷贝通过ICloneable接口来实现。这句话并不正确。事实上任何名字的方法都可以用来实现深拷贝,并且没有任何语法来规定深拷贝只能通过Clone方法来实现。Clone这个名字只是一种习惯的称呼,而实现ICloneable只能带来一般接口的通用便利性,而并没有任何关于拷贝的特殊性。
一般可被继承的类型应该避免实现ICloneable接口,因为这样做将强制所有的子类型都需要实现ICloneable接口,否则将使类型的深拷贝不能覆盖子类的新成员。
二、总结
浅拷贝是指复制类型中的所有值类型成员,而只赋值引用类型成员的引用,并且使目标对象共享原对象的引用类型成员对象。深拷贝是指同时复制值类型成员和引用类型成员的对象。浅拷贝和深拷贝的概念都是递归的。System.Object中的MemberwiseClone已经实现了浅拷贝,但它是一个受保护的方法。无论深拷贝还是浅拷贝,都可以通过实现ICloneable接口的Clone方法来实现,可被继承的类型需要谨慎地实现ICloneable接口,因为这将导致所有的子类型都必须实现ICloneable接口。