Как сделать правильный клон Списка ‹MyObject›?

Возможный дубликат:
Как клонировать общий список на C #?

List<MyObject> a1 = new List<MyObject>();

var new1 = a1;

Теперь, если я изменю a1, то и new1 тоже изменится.

Итак, мой вопрос: как правильно сделать клон a1?


person DmitryBoyko    schedule 08.03.2012    source источник
comment
См .: stackoverflow.com/questions/222598/   -  person Matt Burland    schedule 08.03.2012


Ответы (3)


Это не будет Clone каждый элемент в списке, но создаст вам новый список

var new1 = new List<MyObject>(a1);

Если вы хотите клонировать каждый элемент в списке, вы можете реализовать ICloneable на MyObject

var new1 = new List<MyObject>(a1.Select(x => x.Clone()));

РЕДАКТИРОВАТЬ: чтобы было немного понятнее, оба будут копировать элементы из списка a1 в новый список. Вам просто нужно решить, хотите ли вы иметь новые MyObject или оставить оригиналы. Если вы хотите клонировать MyObject, вам понадобится способ их клонирования, который обычно выполняется с помощью ICloneable.

person aqwert    schedule 08.03.2012
comment
Как его решение не относится ко всем предметам? - person Louis Kottmann; 08.03.2012
comment
var new1 = новый список ‹MyObject› (a1); работает только для типов значений, вам следует обновить свой ответ. - person Brian Ogden; 08.08.2016
comment
var new1 = new List ‹MyObject› (a1.Select (x = ›x.Clone () as MyObject)); - person Steven T. Cramer; 30.10.2018

Или вы можете сделать что-то вроде этого:

public static class CloneClass
{
    /// <summary>
    /// Clones a object via shallow copy
    /// </summary>
    /// <typeparam name="T">Object Type to Clone</typeparam>
    /// <param name="obj">Object to Clone</param>
    /// <returns>New Object reference</returns>
    public static T CloneObject<T>(this T obj) where T : class
    {
        if (obj == null) return null;
        System.Reflection.MethodInfo inst = obj.GetType().GetMethod("MemberwiseClone",
            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        if (inst != null)
            return (T)inst.Invoke(obj, null);
        else
            return null;
    }
}

Затем используйте это как:

var new1 = CloneClass.CloneObject<List<<MyObject>>(a1);
person MAckerman    schedule 08.03.2012
comment
У тебя слишком много «овец». Должно быть ‹Список ‹MyObject›› - person user890332; 13.07.2017

Я думаю, что обычно следует избегать использования Clone, потому что неясно, является ли это мелкой или глубокой копией объекта.

Подробнее об этом здесь: http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx.

Довольно распространенным решением было использование класса BinaryFormatter для сериализации / дериализации объекта и возврата нового экземпляра, но с оговоркой, что класс должен быть сериализуемым:

https://stackoverflow.com/a/1213649/1212407

Исходя из вышеизложенного, вы можете:

var clonedList = originaList.DeepClone();
person Jesse    schedule 08.03.2012