2010-05-26 4 views
2

У меня есть несколько разных классов, которые я хочу быть клонируемыми: GenericRow, GenericRows, ParticularRow и ParticularRows. Существует следующая иерархия классов: GenericRow является родителем ParticularRow, а GenericRows является родителем ParticularRows. Каждый класс реализует 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() 
{ 
    Clone.DeepCopyViaBinarySerialization(this); 
} 
+0

Добавить 'this' в декларацию параметра' T record', и вам даже не нужен метод Clone в каждом классе (т. Е. Переведите DeepCopyViaBinarySerialization в метод расширения). – dtb

+0

ссылка на аргумент против ICloneable: http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx – drewburlingame

1

Реализация ICloneable не является хорошей идеей (см Рекомендации по проектированию Framework).

Реализация метода Clone с BinaryFormatter является ... интересной.

Я бы рекомендовал написать отдельные методы Clone для каждого класса, например.

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

Да, вы много повторяетесь с этим, но это по-прежнему лучшее решение IMHO.

+0

Lol @ 'interesting'. Вот как были сделаны глубокие копии кода, который я получил, и я никогда не потрудился изменить его. –

Смежные вопросы