记得c++里面,struct 和class 的唯一不同点是,class的成员默认是private,struct的则默认是public。
在c#里则不然,struct 默认仍然是private。所以,不禁要问,struct和class有什么区别呢?
struct 是值类型的,而calss是引用类型的。
举个例子,
1 struct Mystruct2 {3 public int x;4 }5 6 class Myclass7 {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:ICloneable44 {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 = 2a.content.con = 1a.x = 2