由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  阅读(3811)  评论(3编辑  收藏  举报

导航

Bye!