Метод клонирования

382
12 апреля 2017, 11:45

Как можно сделать клон объекта на C#? Дело в том, что я работаю над структурой данных "Список", и нужно сделать метод, который будет клонировать список, т.е. создаётся новый список, на основе какого-либо, и с ним можно работать независимо от клонируемого, если я правильно понимаю, если нет, то поясните, что значит клон объекта.

Answer 1

Клон - копия объекта в памяти. Он отличается от исходного тем, что при изменении клона исходный объект не меняется (в отличие от ссылки), также он занимает дополнительную память. Простейший пример клона - MemberwiseClone:

public  class tx {
    public int a;
    public int b;
    public tx Clone() { return (tx)MemberwiseClone(); }
}
static public void Main() {
    tx z1 = new tx();
    z1.a = 0;
    z1.b = 0;
    tx z2 = z1;
    tx z3 = z1.Clone();
    z2.a = 1;
    z3.a = 3;
    Console.Write("z1.a={0} z1.b={1}", z1.a, z1.b);
    Console.Write("z2.a={0} z1.b={1}", z2.a, z2.b);
    Console.Write("z3.a={0} z1.b={1}", z3.a, z3.b);
}

Ну и как вариант снятия "рамок" Microsoft-а:

public T Clone<T>(T obj) {
    return (T)typeof(T).GetMethod("MemberwiseClone", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(obj, null);
}

MemberwiseClone - функция Object, которая находится в секции protected, поэтому она доступна изнутри класса (в примере для этого я создал ф-цию Clone, но, как вариант, её можно вызвать с помощью Reflection). А вот если объект содержит ссылки на объекты, то его клонирование усложняется.

Если вы хотите копировать список, то, боюсь, придётся делать иначе (потому что скопируется экземпляр оболочки списка, а ссылка на весь массив будет такой же):

List<object> newList = new List<object>( srcList.ToArray() );
Dictionary<object,object> newList = new Dictionary<object,object>( srcList.ToArray() );

А если вам нужны копии каждого элемента, то нужно что-то такое (можно переписать с использованием Template):

List<object> CloneList(List<object> srcList) {
    object newArray = new object[srcList.Count]; 
    srcList.CopyTo(newArray);
    return new List<object>(newArray);
}

Последняя функция равносильна по действию Array.Copy. Array.Copy нужна, если просто нужен клон массива.

Answer 2

Например как метод в базовом классе:

public virtual BaseObject ShallowCopy()
{
    return (BaseObject)this.MemberwiseClone();
}
READ ALSO
concat - ошибка Value Buffer или чем заменить concat

concat - ошибка Value Buffer или чем заменить concat

Есть модель Категорий товаров

260
Как правильно остановить Task?

Как правильно остановить Task?

Останавливаю так:

377
Создание копии объекта

Создание копии объекта

Недавно я спрашивал про клонирование объекта, работая с такой структурой данных, как "Список"С методом клонирования разобрался

290