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