記得c++里面,struct 和class 的唯一不同點是,class的成員默認是private,struct的則默認是public。
在c#里則不然,struct 默認仍然是private。所以,不禁要問,struct和class有什么區別呢?
struct 是值類型的,而calss是引用類型的。
舉個例子,
1 struct Mystruct 2 { 3 public int x; 4 } 5 6 class Myclass 7 { 8 public int x; 9 }
如果執行以下代碼,
1 Mystruct st1 = new Mystruct(); 2 st1.x = 1; 3 Mystruct st2 = st1; 4 st2.x = 2; 5 6 Myclass cs1 = new Myclass(); 7 cs1.x = 1; 8 Myclass cs2 = cs1; 9 cs2.x = 2;
那么修改st2不會影響st1,但是修改cs2則同時也修改了cs1. 這就是值類型和引用類型的區別。cs1 和cs2只是一個指針,他們指向同一個地址。所以修改其中任何一個,他們都會同時被修改。
既然有值類型和引用類型之分,我們看一看下面這個初學者容易出錯的例子:
1 Myclass [] array = new Myclass[5]; 2 3 Myclass tmp = new Myclass(); 4 5 for (int i=0;i<5;i++) 6 7 { 8 9 tmp.x = i; 10 11 array[i] = tmp; 12 13 }
array是不是一個x值等於下標的一個類數組呢?答案是否定的,array數組里面,所有的x都等於4.
於是對於類復制,引發了有淺度復制和深度復制等概念。
淺度復制是用過派生於System.Object 的MemberwiseClone()實現的,它可以復制所有值類型,但是對於引用類型,還是只復制了指針。
深度復制需要實現ICloneable借口的Clone()函數,實現引用類型的復制。
看一個例子:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace ConsoleTest 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 CloneExample a = new CloneExample(); 13 a.content = new Content() { con = 1 }; 14 a.x = 2; 15 16 // 淺度復制 17 CloneExample b = (CloneExample) a.ShallowCopy(); 18 b.content.con = 11; 19 b.x = 22; 20 Console.WriteLine("a.content.con = {0}",a.content.con); 21 Console.WriteLine("a.x = {0}", a.x); 22 23 //再試一試深度復制 24 a.content.con = 1; 25 b = (CloneExample)a.Clone(); 26 b.content.con = 11; 27 b.x = 22; 28 Console.WriteLine("a.content.con = {0}", a.content.con);//淺度復制和深度復制的區別體現在,引用類型會不會受影響 29 Console.WriteLine("a.x = {0}", a.x); 30 31 32 33 Console.ReadKey(); 34 } 35 36 37 } 38 39 class Content { 40 public int con; 41 } 42 43 class CloneExample:ICloneable 44 { 45 public int x; 46 public Content content; 47 48 public object ShallowCopy() 49 { 50 return this.MemberwiseClone(); 51 } 52 53 public object Clone() 54 { 55 CloneExample instance = new CloneExample(); 56 instance.x = this.x; 57 instance.content = new Content() { con = this.content.con }; 58 return instance; 59 } 60 } 61 }
使用深度復制,新的變量和就的變量是獨立的,互不影響。
運行結果:
a.content.con = 11
a.x = 2
a.content.con = 1
a.x = 2