不忘本 淺拷貝和深拷貝

2021-09-06 04:03:38 字數 2003 閱讀 7267

返回目錄

clone 分淺拷貝和深拷貝

兩者的區別:當物件中的屬性是引用型別時,即類product中還有對類category的引用時,淺拷貝與深拷貝才有區別。

淺拷貝:複製的是category的引用,當原物件改變時,會影響新物件,反之,亦然。

深拷貝:複製的是category的值,即,它會new乙個新的category,然後將原來的category元素的值複製到新元素,即它與原物件沒有任何關係,只是內容相同。

如何實現物件的拷貝功能:

繼承介面icloneable實現clone方法

icloneable.clone本身並不能區分(deep or shallow)你可以在clone中呼叫memberwiseclone來實現乙個shallowclone也可以自己來實現乙個deepclone。不過按照microsoft的建議當實現icloneable的時候是準備用來實現乙個deepclone。

icloneable.clone返回型別是object

其中memberwiseclone的複製原理是值型別按位複製,引用型別複製物件的引用。這裡有乙個要注意的就是string型別,雖然是引用型別,不過在這裡表現上和值型別是一樣的,在clone的時候就當作值型別來看待好了。

實現clone的方法:

1. 手工轉殖

乙個能夠保證物件完全按照你所想的那樣進行轉殖的方式是手工轉殖物件的每乙個域(field)。這種方式的缺點是麻煩而且容易出錯:如果你在類中增加了乙個域,你很可能會忘記更新clone方法。還要在轉殖引用物件指向原始物件的時候,注意避免無限迴圈引用。下面是乙個進行深拷貝的簡單例子:

2. 使用memberwiseclone方法

memberwiseclone是 object類的受保護方法,能夠通過建立乙個新物件,並把所有當前物件中的非靜態域複製到新物件中,從而建立乙個淺拷貝。對於值型別的域,進行的是按位拷貝。對於引用型別的域,引用會被賦值而引用的物件則不會。因此,原始物件及其轉殖都會引用同乙個物件。注意,這種方法對派生類都是有效的,也就是說,你只需在基類中定義一次clone方法。下面是乙個簡單的例子:

1

public

class

person : icloneable

29 }

3. 用反射進行轉殖

用反射進行轉殖是使用activator.createinstance方法來建立乙個相同型別的新物件,然後用反射對所有域進行淺拷貝。這種方法的優點是它是全自動的,不需要在物件中新增或刪除成員的時候修改轉殖方法。另外它也能被寫成提供深拷貝的方法。缺點是使用了反射,因此會比較慢,而且在部分受信任的環境中是不可用的。示例**

4. 使用序列化進行轉殖

轉殖乙個物件的最簡單的方法是將它序列化並立刻反序列化為乙個新物件。和反射方法一樣,序列化方法是自動的,無需在對物件成員進行增刪的時候做出修改。缺點是序列化比其他方法慢,甚至比用反射還慢,所有引用的物件都必須是可序列化的(serializable)。另外,取決於你所使用的序列化的型別(xml,soap,二進位制)的不同,私有成員可能不能像期望的那樣被轉殖。示例**在這裡,這裡和這裡。

5. 使用il進行轉殖

一種罕見的解決方案是使用il(中間語言)來進行物件轉殖。這種方式建立乙個動態方法(dynamicmethod),獲取中間語言生成器(ilgenerator),向方法中注入**,把它編譯成乙個委託,然後執行這個委託。委託會被快取,因此中間語言只在初次轉殖的時候才會生成,後續的轉殖都不會重新生成一遍。儘管這種方法比使用反射快,但是這種方法難以理解和維護。示例**

6. 使用擴充套件方法進行轉殖

返回目錄

不忘本 explicit和implicit修飾符

返回目錄 部分內容來自msdn implicit關鍵字用於宣告隱式的使用者定義型別轉換運算子。如果轉換過程可以確保不會造成資料丟失,則可使用該關鍵字在使用者定義型別和其他型別之間進行隱式轉換。1 class digit23 67public double val 89 1011 1213 user ...

深拷貝和淺拷貝

淺拷貝就是物件的資料成員之間的簡單賦值,如你設計了乙個沒有類而沒有提供它的複製建構函式,當用該類的乙個物件去給令乙個物件賦值時所執行的過程就是淺拷貝,如 class a a private int data int main 這一句b a 就是淺拷貝,執行完這句後b.data 5 如果物件中沒有其他...

淺拷貝和深拷貝

以下情況都會呼叫拷貝建構函式 乙個物件以值傳遞的方式傳入函式體 例如 已知class a,class b void func a a void func a a func b b 此時函式對b的操作是呼叫拷貝建構函式後的臨時拷貝物件。多數傳指標 乙個物件以值傳遞的方式從函式返回 如 return b...