谈C#对象复制
再談C#對(duì)象復(fù)制????????
對(duì)象復(fù)制的種類:1.C#?不提供復(fù)制構(gòu)造函數(shù)。如果您創(chuàng)建了新的對(duì)象并希望從現(xiàn)有對(duì)象復(fù)制值,您必須自行編寫適當(dāng)?shù)姆椒ā?/span> 示例 在本示例中,2.ICloneable接口來對(duì)對(duì)象進(jìn)行克隆。當(dāng)然,你也可以不去實(shí)現(xiàn)ICloneable接口。 <span style="line-height: 19px; font-family:;" "="" times="" new="" roman';="">???????具體實(shí)現(xiàn)方法: using System;using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace CloneSample
{
????????[Serializable]
????????class CloneClass : ICloneable
????????{
????????????????int num;???????? //值類型
????????????????public int Num //封裝值字段
????????????????{
????????????????????????get { return num; }
????????????????????????set { num = value; }
????????????????}
????????????????string str;????//string引用類型
????????????????public string Str //封裝引用字段
????????????????{
????????????????????????get { return str; }
????????????????????????set { str = value; }
????????????????}
????????????????//數(shù)組引用類型
????????????????public int[] intArr = new int[2];
????????????????//實(shí)現(xiàn)接口的方法
????????????????public Object Clone()
????????????????{
????????????????????????//return this;????????????????????????????????????????//返回同一個(gè)對(duì)象的引用
???????????????????????????? //return this.MemberwiseClone();????//返回一個(gè)淺表副本
????????????????????????????//return new CloneClass();????????????????//返回一個(gè)深層副本
????????????????????????{???????????????????????????????????????????????????????????????? //返回一個(gè)內(nèi)存副本
????????????????????????????????MemoryStream stream = new MemoryStream();
????????????????????????????????BinaryFormatter formatter = new BinaryFormatter();
????????????????????????????????formatter.Serialize(stream, this);
????????????????????????????????stream.Position = 0;
?????????????????????????????????
????????????????????????????????return formatter.Deserialize(stream);
????????????????????????????????
????????????????????????}
????????????????}
????????}
????????//執(zhí)行類
????????class ProgramRun
????????{
????????????????public static void Main()
????????????????{
????????????????????????CloneClass cs = new CloneClass();
????????????????????????//第一次給對(duì)象賦值
???????????????????????cs.Num = 1;
????????????????????????cs.Str = "A";
????????????????????????cs.intArr[0] = 100;
????????????????????????CloneClass cs1 = cs.Clone() as CloneClass;
????????????????????????Console.WriteLine("**************初始化*****************");
????????????????????????Console.WriteLine("cs對(duì)象的值類型:{0}", cs.Num);
????????????????????????Console.WriteLine("cs對(duì)象的string引用類型:{0}", cs.Str);
????????????????????????Console.WriteLine("cs對(duì)象的數(shù)組類型:{0}", cs.intArr[0]);
????????????????????????Console.WriteLine("-------------------------------------------------");
????????????????????????Console.WriteLine("cs1對(duì)象的值類型:{0}", cs1.Num);
????????????????????????Console.WriteLine("cs1對(duì)象的string引用類型:{0}", cs1.Str);
????????????????????????Console.WriteLine("cs1對(duì)象的數(shù)組類型:{0}", cs1.intArr[0]);
????????????????????????//第二次給原始對(duì)象復(fù)制
????????????????????????cs.Num = 2;
????????????????????????cs.Str = "B";
????????????????????????cs.intArr[0] = 200;
????????????????????????//現(xiàn)在我們看看cs和cs1兩個(gè)對(duì)象的值
????????????????????????Console.WriteLine("**************先將cs值改變后變化如下*****************");
????????????????????????Console.WriteLine("cs對(duì)象的值類型:{0}", cs.Num);
???????????????????????Console.WriteLine("cs對(duì)象的string引用類型:{0}", cs.Str);
????????????????????????Console.WriteLine("cs對(duì)象的數(shù)組類型:{0}", cs.intArr[0]);
????????????????????????Console.WriteLine("-------------------------------------------------" );
????????????????????????Console.WriteLine("cs1對(duì)象的值類型:{0}", cs1.Num);
????????????????????????Console.WriteLine("cs1對(duì)象的string引用類型:{0}", cs1.Str);
????????????????????????Console.WriteLine("cs1對(duì)象的數(shù)組類型:{0}", cs1.intArr[0]);
????????????????????????//現(xiàn)在我們給副本對(duì)象進(jìn)行賦值看看原始對(duì)象的值
????????????????????????cs1.Num = 3;
???????????????????????cs1.Str = "C";
????????????????????????cs1.intArr[0] = 300;
????????????????????????Console.WriteLine("**************先將cs1值改變后變化如下*****************");
????????????????????????Console.WriteLine("cs對(duì)象的值類型:{0}", cs.Num);
????????????????????????Console.WriteLine("cs對(duì)象的string引用類型:{0}", cs.Str);
????????????????????????Console.WriteLine("cs對(duì)象的數(shù)組類型:{0}", cs.intArr[0]);
????????????????????????Console.WriteLine("-------------------------------------------------");
????????????????????????Console.WriteLine("cs1對(duì)象的值類型:{0}", cs1.Num);
???????????????????????Console.WriteLine("cs1對(duì)象的string引用類型:{0}", cs1.Str);
????????????????????????Console.WriteLine("cs1對(duì)象的數(shù)組類型:{0}", cs1.intArr[0]);
????????????????????????Console.WriteLine("Output Complete!Press Any Key To Continue.");
????????????????????????Console.ReadKey();
????????????????}
????????}
} 輸出結(jié)果分析: 1.?返回同一個(gè)對(duì)象的引用的結(jié)果: cs對(duì)象的值類型:2 cs對(duì)象的string引用類型:B cs對(duì)象的數(shù)組類型:200 cs1對(duì)象的值類型:2 cs1對(duì)象的string引用類型:B cs對(duì)象的數(shù)組類型:200 cs對(duì)象的值類型:3 cs對(duì)象的string引用類型:C cs對(duì)象的數(shù)組類型:300 可以看到,cs和cs1完全是同一個(gè)對(duì)象,cs修改,cs1的值也跟著改變;cs1修改,cs也跟著改變。 2.返回一個(gè)淺表副本的結(jié)果: cs對(duì)象的值類型:2 cs對(duì)象的string引用類型:B cs對(duì)象的數(shù)組類型:200 cs1對(duì)象的值類型:1 cs1對(duì)象的string引用類型:A cs對(duì)象的數(shù)組類型:200 cs對(duì)象的值類型:2 cs對(duì)象的string引用類型:B cs對(duì)象的數(shù)組類型:300 這個(gè)結(jié)果可以看出,淺表副本和原始副本并不是一個(gè)對(duì)象,但是,淺表副本復(fù)制了原始對(duì)象的值類型和string類型,但是數(shù)組只復(fù)制了引用。這個(gè)現(xiàn)象很有趣,按照MSDN的定義:“MemberwiseClone?方法創(chuàng)建一個(gè)淺表副本,方法是創(chuàng)建一個(gè)新對(duì)象,然后將當(dāng)前對(duì)象的非靜態(tài)字段復(fù)制到該新對(duì)象。如果字段是值類型的,則對(duì)該字段執(zhí)行逐位復(fù)制。如果字段是引用類型,則復(fù)制引用但不復(fù)制引用的對(duì)象;因此,原始對(duì)象及其復(fù)本引用同一對(duì)象。”,但是,在實(shí)際上,string應(yīng)該也是引用類型,但是,淺表副本卻復(fù)制了這個(gè)值。 3?返回一個(gè)深層副本的結(jié)果 cs對(duì)象的值類型:2 cs對(duì)象的string引用類型:B cs對(duì)象的數(shù)組類型:200 cs1對(duì)象的值類型:0 cs1對(duì)象的string引用類型: cs對(duì)象的數(shù)組類型:0 cs對(duì)象的值類型:2 cs對(duì)象的string引用類型:B cs對(duì)象的數(shù)組類型:200 從結(jié)果可以看到,深層副本完全復(fù)制了對(duì)象的結(jié)構(gòu)。 4.返回一個(gè)內(nèi)存副本的結(jié)果 cs對(duì)象的值類型:2 cs對(duì)象的string引用類型:B cs對(duì)象的數(shù)組類型:200 cs1對(duì)象的值類型:1 cs1對(duì)象的string引用類型:A cs對(duì)象的數(shù)組類型:100 cs對(duì)象的值類型:2 cs對(duì)象的string引用類型:B cs對(duì)象的數(shù)組類型:200 從結(jié)果看出,內(nèi)存深層復(fù)制完全對(duì)原始對(duì)象進(jìn)行了復(fù)制。
總結(jié)
- 上一篇: 推辞掉得不是你的工作,而是你的未来
- 下一篇: C#复制和深度复制的实现方法