由struct 和class 想到的浅度复制和深度复制 c#
记得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
posted on 2012-07-12 17:19 leavingseason 阅读(3833) 评论(3) 编辑 收藏 举报