2010-05-26 57 views
2

我有幾個不同的類,我想要可複製:GenericRow,GenericRows,ParticularRowParticularRows。有以下類層次結構:GenericRowParticularRow的父級,GenericRowsParticularRows的父級。每個類實現ICloneable,因爲我想能夠創建每個實例的深層副本。我發現自己寫完全相同的代碼爲Clone()每一類:幹幾個類的ICloneable的實現

object ICloneable.Clone() 
{ 
    object clone; 

    using (var stream = new MemoryStream()) 
    { 
     var formatter = new BinaryFormatter(); 

     // Serialize this object 
     formatter.Serialize(stream, this); 
     stream.Position = 0; 

     // Deserialize to another object 
     clone = formatter.Deserialize(stream); 
    } 

    return clone; 
} 

然後我在GenericRows提供一個便利的包裝方法,例如:

public GenericRows Clone() 
{ 
    return (GenericRows)((ICloneable)this).Clone(); 
} 

我很好的便利包裝方法尋找因爲它的代碼非常少,所以確實不一樣因類別不同而不同,但是,ICloneable.Clone()相同在所有四個類別中。我能否以某種方式抽象出它,因此它只能在一個地方定義?我擔心的是,如果我製作了一些實用程序類/ object擴展方法,它不會正確地複製要複製的特定實例的深層副本。無論如何,這是一個好主意嗎?

回答

2

正在召開會議,因此只有時間向您投擲一些代碼。

public static class Clone 
{ 
    public static T DeepCopyViaBinarySerialization<T>(T record) 
    { 
     using (MemoryStream memoryStream = new MemoryStream()) 
     { 
      BinaryFormatter binaryFormatter = new BinaryFormatter(); 
      binaryFormatter.Serialize(memoryStream, record); 
      memoryStream.Position = 0; 
      return (T)binaryFormatter.Deserialize(memoryStream); 
     } 
    } 
} 

從克隆方法中:

Clone() 
{ 
    Clone.DeepCopyViaBinarySerialization(this); 
} 
+0

將'this'添加到'T record'參數聲明中,並且在每個類中甚至不需要克隆方法(即將DeepCopyViaBinarySerialization轉換爲擴展方法)。 – dtb 2010-05-26 17:33:23

+0

反對ICloneable的參數鏈接:http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx – drewburlingame 2010-05-26 18:19:45

1

實現ICloneable是不是一個好主意(見框架設計指南)。

使用BinaryFormatter實現克隆方法是....很有趣。

我實際上建議爲每個班級編寫單獨的克隆方法,例如,

public Class1 Clone() 
{ 
    var clone = new Class1(); 
    clone.ImmutableProperty = this.ImmutableProperty; 
    clone.MutableProperty = this.MutableProperty.Clone(); 
    return clone; 
} 

是的,你重複了很多與此,但它仍然是最好的解決方案恕我直言。

+0

Lol @'有趣的'。這就是我給出的代碼的深度拷貝,我從來沒有打算改變它。 – 2010-05-26 18:00:31