Как реализовать метод клонирования и копирования внутри класса?
У меня есть класс с именем 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();
}
}
Ответ 4
Проверьте это клонирование объектов с помощью IL в С# http://whizzodev.blogspot.com/2008/03/object-cloning-using-il-in-c.html
Ответ 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();