1. 程式人生 > >關於C#中深拷貝和淺拷貝的認識

關於C#中深拷貝和淺拷貝的認識

首先說我理解的一些基本概念(若有不對,歡迎指點)

記憶體:用來儲存程式資訊的介質。

指標:指向一塊記憶體區域,通過它可以訪問該記憶體區域中儲存的程式資訊。(C#也是有指標的)

值型別:struct(整形、浮點型、decimal的內部實現都是struct)、enum、可空型別

引用型別:class、interface、delegate、陣列、object、string。

下面說我對深拷貝和淺拷貝的認識:

舉個例子:

Myclass a=new Myclass();

Myclass b=a;

首先,深、淺拷貝與上面的語句並沒有任何關係,要區分深、淺拷貝,關鍵要看“=”是如何過載的。

深拷貝:不管是值型別還是引用型別,都在記憶體中新建一塊儲存塊,該儲存塊的內容(由b指向)與被拷貝的儲存塊(由a指向)的內容相同,並新建一個指標(b)指向該新建的儲存塊。所以對b的操作是不會影響a。

淺拷貝:對於值型別,拷貝一份值的副本;對於引用型別,拷貝一份指標的副本(該副本仍然指向原指標指向的記憶體塊,即a、b指向同一塊記憶體)。對b的值型別進行操作,不會影響a;對b的引用型別進行操作,會影響a。

對於淺拷貝,有一種奇怪的現象,即:若a中包含一個string型別的欄位,對a進行淺拷貝,賦值給b,在b中改變這個string型別的欄位,a中string型別欄位不受影響。string型別明明是引用型別,按照上面的理解,修改b中的string欄位,a中的string欄位也該作出相應的改變,這是為什麼呢?

我們不妨看看string的定義,會發現string被readonly關鍵字修飾了,即改變string的值時,就會重新分配記憶體空間。有興趣的話可以瞭解一下“C#字串不可變性”。