clone是深拷貝,copy是淺拷貝,如果是值類型的話是沒什么區別的,如果是引用類型的話深拷貝拷貝的事整個對象的數據,而淺拷貝僅僅拷貝對象的引用。因為類的實例是引用類型,要想用原有的類中的實例的數據的話,既要想創建原對象的一個副本的話,只能用clone方法。Clone方法分為深clone和淺clone 。
實現Clone的方法
手工克隆
一個能夠保證對象完全按照你所想的那樣進行克隆的方式是手工克隆對象的每一個域(field)。這種方式的缺點是麻煩而且容易出錯:如果你在類中增加了一個域,你很可能會忘記更新Clone方法。還要在克隆引用對象指向原始對象的時候,注意避免無限循環引用。
使用MemberWiseClone方法
MemberWiseClone是Object類的受保護方法,能夠通過創建一個新對象,并把所有當前對象中的非靜態域復制到新對象中,從而創建一個淺拷貝。對于值類型的域,進行的是按位拷貝。對于引用類型的域,引用會被賦值而引用的對象則不會。因此,原始對象及其克隆都會引用同一個對象。注意,這種方法對派生類都是有效的,也就是說,你只需在基類中定義一次Clone方法。
用反射進行克隆
用反射進行克隆是使用Activator.CreateInstance方法來創建一個相同類型的新對象,然后用反射對所有域進行淺拷貝。這種方法的優點是它是全自動的,不需要在對象中添加或刪除成員的時候修改克隆方法。另外它也能被寫成提供深拷貝的方法。缺點是使用了反射,因此會比較慢,而且在部分受信任的環境中是不可用的。
使用序列化進行克隆
克隆一個對象的最簡單的方法是將它序列化并立刻反序列化為一個新對象。和反射方法一樣,序列化方法是自動的,無需在對對象成員進行增刪的時候做出修改。缺點是序列化比其他方法慢,甚至比用反射還慢,所有引用的對象都必須是可序列化的(Serializable)。另外,取決于你所使用的序列化的類型(XML,SOAP,二進制)的不同,私有成員可能不能像期望的那樣被克隆。
代碼
///
///?Reference?Article?http://www.codeproject.com/KB/tips/SerializedObjectCloner.aspx
///?Provides?a?method?for?performing?a?deep?copy?of?an?object.
///?Binary?Serialization?is?used?to?perform?the?copy.
///
public?static?class?ObjectCopier
{//////?Perform?a?deep?Copy?of?the?object.//////?The?type?of?object?being?copied.///?The?object?instance?to?copy.///?The?copied?object.public?static?T?Clone(this?T?source){if?(!typeof(T).IsSerializable){throw?new?ArgumentException("The?type?must?be?serializable.",?"source");}//?Don't?serialize?a?null?object,?simply?return?the?default?for?that?objectif?(Object.ReferenceEquals(source,?null)){return?default(T);}IFormatter?formatter?=?new?BinaryFormatter();Stream?stream?=?new?MemoryStream();using?(stream){formatter.Serialize(stream,?source);stream.Seek(0,?SeekOrigin.Begin);return?(T)formatter.Deserialize(stream);}}
}