由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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM