Как реализовать метод клонирования и копирования внутри класса?

У меня есть класс с именем Employee с 3 свойством ID, Name, Dept. Мне нужно реализовать методы Copy и Clone? Когда я использую метод Copy или Clone, мне нужно избегать Casting? как я это сделаю?

пример: тот же, что и DataTable, который имеет DataTable.Copy() и DataTable.Clone().

Ответ 1

Вам нужно реализовать интерфейс IClonable и обеспечить реализацию метода clone. Не применять это, если вы хотите избежать кастинга.

Простым методом глубокого клонирования может быть сериализация объекта в памяти, а затем десериализация. Все пользовательские типы данных, используемые в вашем классе, должны быть сериализованы с использованием атрибута [Serializable]. Для клона вы можете использовать что-то вроде

  public MyClass Clone()
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();

        bf.Serialize(ms, this);

        ms.Position = 0;
        object obj = bf.Deserialize(ms);
        ms.Close();

        return obj as MyClass;
    }

Если ваш класс имеет типы значений, вы можете использовать конструктор копирования или просто присвойте значения новому объекту в методе Clone.

Ответ 2

Вам нужно использовать интерфейс ICloneable или достаточно, если у вас есть только два метода под названием Clone и Copy, которые определены в общем интерфейсе?

public class YourClass : ICloneable<YourClass>
{
    // Constructor logic should be here
    public YourClass Copy() { return this; }        
    public YourClass Clone() { return new YourClass(ID, Name, Dept); }
}

interface  IClonable<T>
{
    T Copy();
    T Clone();
}

Или я что-то не понял?

То, что я пытаюсь сказать, заключается в том, что вам не нужно делать это более сложным, чем это? Если вам нужно, чтобы ваши объекты соответствовали кому-то, вы можете написать его самостоятельно, если тот, который указан в структуре .Net, является сложным для ситуации. Вы также должны определить разницу с Clone и Copy, то есть, что они означают для вас? Я знаю, что существует несколько сайтов, указывающих, что Clone является глубокой копией, а Copy является мелкой копией.

Ответ 3

Вы имеете в виду, как реализовать ICloneable.Clone() и вернуть ему тип самого класса.

public class MyType : ICloneable
{
  public MyType Clone() //called directly on MyType, returns MyType
  {
    return new MyType(/* class-dependant stuff goes here */);
  }
  object ICloneable.Clone() // called through ICloneable interface, returns object
  {
    return Clone();
  }
}

Ответ 5

Я часто вижу конструкторы копирования, предложенные в качестве альтернативы методу клонирования, но, за исключением закрытых классов, поведение сильно отличается. Если у меня есть тип Car, который просто поддерживает свойства VIN, BodyColor и BodyStyle, а также производный тип FancyCar, который также поддерживает InteriorFabric и SoundSystem, тогда код, который принимает объект типа Car, и использует конструктор копий автомобилей для его дублирования, закончится с автомобилем. Если FancyCar передается в такой код, получившийся "дубликат" будет новым автомобилем, который имеет VIN, BodyColor и BodyStyle, которые соответствуют оригинальному автомобилю, но не будут иметь ни интерьер, ни саундсистему. Напротив, код должен был принять Автомобиль и использовать на нем метод клонирования, передача FancyCar в код приведет к созданию FancyCar.

Если никто не хочет использовать Reflection, любой метод клонирования должен в своей базе включать вызов base.MemberwiseClone. Поскольку MemberwiseClone не является виртуальным методом, я бы предложил определить метод защищенного виртуального клонирования; вы также можете запретить любым дочерним классам вызвать MemberwiseClone, указав фиктивный вложенный класс защищенной области с тем же именем (поэтому, если класс потомков пытается вызвать base.MemberwiseClone, это не будет интерпретироваться как бессмысленная ссылка на фиктивный класс).

Ответ 6

Вот пример:

namespace XXX
{
     [Serializable]
    public class ItemChecklist : ICloneable
    {

       // [...here properties, attributes, etc....]



        object ICloneable.Clone()
        {
            return this.Clone();
        }
        public ItemChecklist Clone()
        {
            return (ItemChecklist)this.MemberwiseClone();
        }


    }
}

i.e Если вы используете эту функцию, у вас будет "itemAdd" целая копия объекта "itemTemp" со всеми его значениями.

ItemChecklist itemAdd = itemTemp.Clone();