Подтвердить что ты не робот

Как сделать правильный клон списка <MyObject>?

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

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

var new1 = a1;

Теперь, если я изменю a1, тогда будет также изменен new1.

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

4b9b3361

Ответ 1

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

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

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

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

EDIT: Чтобы сделать его более понятным, оба будут скопировать элементы из списка a1 в новый список. Вам просто нужно решить, хотите ли вы иметь новый MyObject или сохранить оригиналы. Если вы хотите клонировать MyObject, вам понадобится способ клонирования, который обычно выполняется через ICloneable.

Ответ 2

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

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);

Ответ 3

Я считаю, что общая практика заключается в том, чтобы избежать использования Clone, потому что это не ясно, если это Shallow vs Deep copy объекта.

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

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

fooobar.com/info/2370/...

Предполагая вышесказанное, вы можете сделать:

var clonedList = originaList.DeepClone();