该接口使你能够创建现有对象的副本的自定义的实现。该接口只提供了,一个Clone方法,实现对象的浅拷贝。有浅拷贝,那么就有相对应的深拷贝。但该接口并没有对我们提供,需要我们自己实现。
什么是浅拷贝与深拷贝?浅拷贝
将对象的字段复制到新的对象副本中,同时将字段的值也复制过去,但引用类型值复制引用,而不是引用类型本身,也就是,如果源对象的引用类型的字段的值改变了,拷贝的对象的对应的引用类型的字段也会跟着变化。
深拷贝
将对象的字段复制到新的对象副本中,无论是值类型还是引用类型的字段,都会复制类型本身及值。但,源对象的值变化,并不会影响副本中的对应的值。
一个例子浅拷贝
<span >namespace<span > Wolfy.CloneDemo{
<span >class<span > Program
{
<span >static <span >voID Main(<span >string<span >[] args)
{
Console.Writeline(<span >"<span >创建新对象:<span >"<span >);
Person p = <span >new Person() { name = <span >"<span >wolfy<span >",ID = <span >1,Address = <span >new Address { City = <span >"<span >北京<span >",Details = <span >"<span >北京 海淀区<span >"<span > } };
Console.Writeline(p.ToString());
Console.Writeline(<span >"<span >克隆对象:<span >"<span >);
Person p2 =<span > (Person)p.Clone();
Console.Writeline(p2.ToString());
<span >var result = <span >object<span >.ReferenceEquals(p,p2);
Console.Writeline(<span >"<span >p ReferenceEquals p2:<span >" +<span > result);
Console.Writeline(<span >"<span >此时修改p对象,是否会影响p2对象?<span >"<span >);
p.name = <span >"<span >wolfy2<span >"<span >;
p.ID = <span >2<span >;
p.Address.City = <span >"<span >上海<span >"<span >;
Console.Writeline(<span >"<span >p:<span >" +<span > p.ToString());
Console.Writeline(<span >"<span >p2:<span >" +<span > p2.ToString());
Cons<a href="https://m.jb51.cc/tag/ol/" target="_blank" >ol</a>e.Read(); }}[Seria<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>zable]</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">class</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> Person : ICloneable{ </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;">///</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;"><summary></span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;">///</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"> 值类型 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;">///</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;"></summary></span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">private</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">int</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> _<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;">///</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;"><summary></span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;">///</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"> 特殊的引用类型 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;">///</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #808080;"></summary></span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">private</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">string</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> _<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">private</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> Address _address; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">int</span> <a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a> { <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">get</span> => _<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>; <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">set</span> => _<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a> =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> value; } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">string</span> <a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a> { <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">get</span> => _<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a>; <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">set</span> => _<a href="https://m.jb51.cc/tag/name/" target="_blank" >name</a> =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> value; } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> Address Address { <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">get</span> => _address; <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">set</span> => _address =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> value; } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">overr<a href="https://m.jb51.cc/tag/ID/" target="_blank" >ID</a>e</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">string</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> ToString() { </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">return</span> <a href="https://m.jb51.cc/tag/Js/" target="_blank" >Js</a>onConvert.Seria<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>zeObject(<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">this</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;">); } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">object</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> Clone() { </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;">/*</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;"> MemberwiseClone<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a><a href="https://m.jb51.cc/tag/chuangjian/" target="_blank" >创建</a>的新对象,<a href="https://m.jb51.cc/tag/ranhou/" target="_blank" >然后</a>将当前对象的非静态字段复制到新的<a href="https://www.jb51.cc/tag/duixiangchuangjian/" target="_blank" >对象创建</a>的浅表副本。 如果字段是值类型,则执行字段的按位复制。 如果字段是引用类型,引用将复制,但被引用的对象不; 因此,原始对象和其克隆引用同一对象。 例如,考虑对象称为 X 引用对象 A 和 B,反过来,引用对象 c。 X 的浅表副本<a href="https://m.jb51.cc/tag/chuangjian/" target="_blank" >创建</a>新的对象 X2 也引用对象 A 和 b。与此相反, X 的深层副本<a href="https://m.jb51.cc/tag/chuangjian/" target="_blank" >创建</a>新对象 X2 引用 A2 和 B2, 是的<a href="https://www.jb51.cc/tag/yige/" target="_blank" >一个</a>副本的新对象并 B.B2, 反过来,引用新对象 C2,这是 C 的副本。该示例说明浅和深层复制 *** 作之<a href="https://www.jb51.cc/tag/jiande/" target="_blank" >间的</a>差异。 有很多<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a>可以实现深层复制 *** 作,如果浅表复制 *** 作由MemberwiseClone<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a>并不满足你的需求。 这些要求<a href="https://www.jb51.cc/tag/baokuo/" target="_blank" >包括</a>: <a href="https://www.jb51.cc/tag/diaoyong/" target="_blank" >调用</a>类构造<a href="https://www.jb51.cc/tag/hanshu/" target="_blank" >函数</a>要复制可以<a href="https://m.jb51.cc/tag/shiyong/" target="_blank" >使用</a>来自第<a href="https://www.jb51.cc/tag/yige/" target="_blank" >一个</a>对象的<a href="https://www.jb51.cc/tag/shuxing/" target="_blank" >属性</a>值<a href="https://m.jb51.cc/tag/chuangjian/" target="_blank" >创建</a>第二个对象的对象。 这假定,对象的值完全由其类构造<a href="https://www.jb51.cc/tag/hanshu/" target="_blank" >函数</a>中定义。 <a href="https://www.jb51.cc/tag/diaoyong/" target="_blank" >调用</a>MemberwiseClone<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a><a href="https://m.jb51.cc/tag/chuangjian/" target="_blank" >创建</a><a href="https://www.jb51.cc/tag/yige/" target="_blank" >一个</a>对象, 对象的浅表副本并将其值是与原始对象的任何<a href="https://www.jb51.cc/tag/shuxing/" target="_blank" >属性</a>或其值是引用类型的字段相同的新对象。 Deep<a href="https://www.jb51.cc/tag/cop/" target="_blank" >cop</a>y<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a>在示例中演示了此<a href="https://www.jb51.cc/tag/fangfa/" target="_blank" >方法</a>。 序列化对象是较深复制,,<a href="https://m.jb51.cc/tag/ranhou/" target="_blank" >然后</a>将序列化的数据还原到另<a href="https://www.jb51.cc/tag/yige/" target="_blank" >一个</a>对象变量。 <a href="https://m.jb51.cc/tag/shiyong/" target="_blank" >使用</a>具有递归反射来执行深层复制 *** 作。 </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #008000;">*/</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">return</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">this</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;">.MemberwiseClone(); } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">object</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> DeepClone() { </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">using</span> (Stream objectStream = <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> MemoryStream()) { IFormatter formatter </span>= <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">new</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> BinaryFormatter(); formatter.Seria<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ze(objectStream,</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">this</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;">); objectStream.Seek(</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #800080;">0</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;">,SeekOrigin.Begin); </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">return</span> formatter.Deseria<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>ze(objectStream) <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">as</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> Person; } }}[Seria<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>zable]</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">class</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> Address{ </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">private</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">string</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> _city; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">private</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">string</span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> _details; </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">string</span> City { <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">get</span> => _city; <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">set</span> => _city =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> value; } </span><span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">pub<a href="https://m.jb51.cc/tag/li/" target="_blank" >li</a>c</span> <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">string</span> Details { <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">get</span> => _details; <span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #0000ff;">set</span> => _details =<span https://m.jb51.cc/tag/color/" target="_blank" >color</a>: #000000;"> value; }}
}
如上图所示,浅拷贝,值类型的并不会相互影响,但是引用类型的Address会跟着改变。浅拷贝,在对引用类型的字段时,会拷贝指向该对象的引用。
深拷贝
将
Person p2 = (Person)p.Clone();改为
Person p2 = (Person)p.DeepClone();结语在实际项目中,这个接口自己是没用过。在看c#相关的文章的时候,看到了该接口的介绍,一篇文章了解下。如果非要说应用场景的话,比如,如果一个方法参数是一个引用类型,你需要在方法中对其进行 *** 作,但又不想改变它原有的值,可以实现该接口,在clone实现深拷贝,对拷贝的副本进行 *** 作,不影响它的原有的值,返回一个新的对象。
总结以上是内存溢出为你收集整理的[c#基础]ICloneable接口全部内容,希望文章能够帮你解决[c#基础]ICloneable接口所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)