如何正确地克隆 List<MyObject>?

14

可能是重复问题:
如何在C#中克隆一个泛型列表?

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

var new1 = a1;

现在,如果我更改 a1,那么 new1 也会被更改。

所以我的问题是如何正确地克隆 a1


2
请参见:https://dev59.com/sHVC5IYBdhLWcg3wpi98 - Matt Burland
3个回答

35

这不会对列表中的每个项进行Clone,但会为您创建一个新列表

var new1 = new List<MyObject>(a1);
如果你想克隆列表中的每个项,可以在 MyObject 上实现 ICloneable 接口。
var new1 = new List<MyObject>(a1.Select(x => x.Clone()));

编辑: 为了让它更清晰一些,两者都将把列表a1中的元素复制到一个新列表中。您只需要决定是要新的MyObject还是保留原始对象。如果您想克隆MyObject,则需要一种克隆它们的方法,通常是通过ICloneable完成。


6
他的解决方案为什么没有处理所有的物品? - Louis Kottmann
3
var new1 = new List<MyObject>(a1); 只适用于值类型,您应该更新您的答案。 - Brian Ogden
var new1 = new List<MyObject>(a1.Select(x => x.Clone() as MyObject)); 新建一个列表new1,它包含了a1中每个元素的克隆对象MyObject。 - Steven T. Cramer

4
或者,您可以像这样做:

或者,您也可以这样做:

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

您的“<”符号多了一个。 应该是 <List<MyObject>>。 - user890332

1

我认为通常的做法是避免使用Clone,因为它不清楚它是对象的浅拷贝还是深拷贝。

关于这个问题的更多信息: http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx

一个相当普遍的解决方案是使用BinaryFormatter类对对象进行序列化/反序列化,并返回新实例,但必须注意该类必须可序列化:

https://dev59.com/DnVC5IYBdhLWcg3w-WWs#1213649

假设以上情况,你可以这样做:

var clonedList = originaList.DeepClone();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接