Высушивание реализации ICloneable в нескольких классах - PullRequest
2 голосов
/ 26 мая 2010

У меня есть несколько разных классов, которые я хочу клонировать: GenericRow, GenericRows, ParticularRow и ParticularRows. Существует следующая иерархия классов: GenericRow является родителем ParticularRow, а GenericRows является родителем ParticularRows. Каждый класс реализует ICloneable, потому что я хочу иметь возможность создавать глубокие копии экземпляров каждого. Я пишу один и тот же код для Clone() в каждом классе:

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 ]

2 голосов
/ 26 мая 2010

отправляйтесь на собрание, так что успейте набросать на вас какой-нибудь код.

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);
}
1 голос
/ 26 мая 2010

Реализация ICloneable - не очень хорошая идея (см. Руководство по проектированию платформы).

Реализация метода Clone с помощью BinaryFormatter ... интересна.

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

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

Да, вы многократно повторяете это, но, тем не менее, это лучшее решение ИМХО.

...