2013-06-12 79 views

回答

1

您不應該使用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

+0

感謝您的回答。布拉德艾布拉姆斯的帖子也很古老(2004年)。我需要我的對象的影子克隆。你如何看待Object.MemberwiseClone方法? http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx PS - 序列化/反序列化的方式看起來很糟糕。Allredy發現3或4個不同的實現 – jimpanzer

+0

pps現在我正在閱讀當前Jeffrey Richters的書) – jimpanzer

+0

@jimpanzer閱讀序列化部分,它非常有趣。 ;)無論如何,我不會使用'MemberwiseClone()',因爲它只是一個*淺*克隆 - 除非你只想要一個淺層克隆,當然。 –

3

IClonable只是一個接口,所以它沒有什麼都沒有,直到你實現它。建議不使用IClonable的帖子提到了爲什麼:Clone被實現爲深度拷貝或淺度拷貝並不清楚。

因此,只需提供一個CopyDeepClone方法,每個人都知道會發生什麼。

引用來解釋這兩個術語:

一般有兩種方法來實現ICloneable,無論是作爲一個, 或非深副本。深度複製以遞歸方式複製對象引用的克隆對象和所有對象 ,直到複製圖 中的所有對象。非深度複製(如果僅複製頂級 級別引用,則稱爲)可能不會執行任何操作,也可能不執行深度複製操作。

+0

感謝您的回答。我需要我的對象的影子克隆。你如何看待Object.MemberwiseClone方法? http://msdn.microsoft.com/en-us/library/system.object.memberwiseclone.aspx – jimpanzer