我需要在.net 4.5(c#)中克隆對象(類,而不是struct)。
我發現有兩種方式:創建對象的副本
- 實施ICloneable Interface
- 創建自己的克隆機制像this famous SO answer
我喜歡拳的方式 - 這是更容易,但我也發現Not Implpement ICloneable Interface,但它是很老樁在MSDN上,我無法找到此接口已棄用。
任何人都可以說我在.net 4.5中使用ICloneable是安全的嗎?
我需要在.net 4.5(c#)中克隆對象(類,而不是struct)。
我發現有兩種方式:創建對象的副本
我喜歡拳的方式 - 這是更容易,但我也發現Not Implpement ICloneable Interface,但它是很老樁在MSDN上,我無法找到此接口已棄用。
任何人都可以說我在.net 4.5中使用ICloneable是安全的嗎?
您不應該使用IClonable接口。
Here's a blog from Brad Abrams discussing why not從幾年前。基本上,Tim Schmelter的回答概述了這個原因,但是這個博客來自馬匹的口中。
關於通過序列化實現克隆,現在有一種更好的方法可用,因爲我們可以指定StreamingContextStates.Clone
以允許克隆更好地使用非託管句柄。
有「通過C#第四版CLR」在規範執行由傑弗裏裏希特這是這樣的:
public static object DeepClone(object original)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter
{
Context = new StreamingContext(StreamingContextStates.Clone)
};
formatter.Serialize(stream, original);
stream.Position = 0;
return formatter.Deserialize(stream);
}
}
或者強類型的變體:
public static T DeepClone<T>(T original)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "original");
}
if (ReferenceEquals(original, null))
{
return default(T);
}
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter
{
Context = new StreamingContext(StreamingContextStates.Clone)
};
formatter.Serialize(stream, original);
stream.Position = 0;
return (T) formatter.Deserialize(stream);
}
}
我想你應該使用(在可能的情況下)而不是實施IClonable
。
IClonable
只是一個接口,所以它沒有什麼都沒有,直到你實現它。建議不使用IClonable
的帖子提到了爲什麼:Clone
被實現爲深度拷貝或淺度拷貝並不清楚。
因此,只需提供一個Copy
或DeepClone
方法,每個人都知道會發生什麼。
引用來解釋這兩個術語:
一般有兩種方法來實現ICloneable,無論是作爲一個深, 或非深副本。深度複製以遞歸方式複製對象引用的克隆對象和所有對象 ,直到複製圖 中的所有對象。非深度複製(如果僅複製頂級 級別引用,則稱爲淺)可能不會執行任何操作,也可能不執行深度複製操作。
感謝您的回答。我需要我的對象的影子克隆。你如何看待Object.MemberwiseClone方法? http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx – jimpanzer
感謝您的回答。布拉德艾布拉姆斯的帖子也很古老(2004年)。我需要我的對象的影子克隆。你如何看待Object.MemberwiseClone方法? http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx PS - 序列化/反序列化的方式看起來很糟糕。Allredy發現3或4個不同的實現 – jimpanzer
pps現在我正在閱讀當前Jeffrey Richters的書) – jimpanzer
@jimpanzer閱讀序列化部分,它非常有趣。 ;)無論如何,我不會使用'MemberwiseClone()',因爲它只是一個*淺*克隆 - 除非你只想要一個淺層克隆,當然。 –