Clone 分淺拷貝和深拷貝

2022-07-16 08:15:19 字數 2364 閱讀 6065

兩者的區別:當有引用型別成員時,淺拷貝複製的是成員的引用,深拷貝複製的是成員物件。

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

繼承介面icloneable實現clone方法

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

icloneable.clone返回型別是object

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

實現clone的方法:

1. 手工轉殖

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

public

enum warn

///
/// 泛型類
/// 

/// 

/// 

public

class compare: icloneable where t1 : class

catch (exception)
}
#region icloneable members
public

object clone()

#endregion
}

people p1 = new people ;
people p2 = new people ;
comparec = new compare();
c.copyentity(p1, ref p2);

2. 使用memberwiseclone方法

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

public class person :icloneable}
3. 用反射進行轉殖

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

4. 使用序列化進行轉殖

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

5. 使用il進行轉殖

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

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

clone的深拷貝與淺拷貝

想要了解淺拷貝和深拷貝之前,要了解的是值傳遞和引用傳遞。值傳遞 傳遞的是變數的值,對該值進行修改不會影響原來變數的值 引用傳遞 傳遞的是變數的在堆中的引用,修改其值,會影響實際變數 這裡只是簡單的介紹,想要詳細了解的話,建議檢視其他部落格 知道了值傳遞和引用傳遞就可以來了解淺拷貝和深拷貝了 淺拷貝 ...

Object的clone 方法 深拷貝 淺拷貝

乙個物件直接使用 比如object o1 new object object o2 o1 那麼問題是o1改變,o2也會改變。這時候,需要不隨之前的物件改變而改變,使用clone。需要注意clone是protect的,所以子類繼承object 否則丟擲異常 public teacher clone c...

深拷貝和淺拷貝

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