【问题标题】:How to make correct clone of the List<MyObject>? [duplicate]如何正确克隆 List<MyObject>? [复制]
【发布时间】:2012-03-26 04:54:44
【问题描述】:

可能重复:
How do I clone a generic list in C#?

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

var new1 = a1;

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

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

【问题讨论】:

标签: c# .net generics generic-list


【解决方案1】:

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

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

如果你想克隆列表中的每个项目,你可以在MyObject上实现ICloneable

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

编辑: 为了更清楚一点,两者都会将列表 a1 中的元素复制到一个新列表中。您只需要决定是否要拥有新的MyObjects 或保留原件。如果你想克隆MyObject,你需要一种方法来克隆它们,这通常是通过ICloneable完成的。

【讨论】:

  • 他的解决方案怎么不处理所有项目?
  • var new1 = new List(a1);仅适用于值类型,您应该更新您的答案。
  • var new1 = new List(a1.Select(x => x.Clone() as MyObject));
【解决方案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,因为不清楚它是对象的浅拷贝还是深拷贝。

更多关于这里: http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx

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

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

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

var clonedList = originaList.DeepClone();

【讨论】:

    猜你喜欢
    • 2017-05-19
    • 2014-10-08
    • 1970-01-01
    • 2016-05-18
    • 2014-10-22
    • 1970-01-01
    • 2012-07-27
    • 2010-10-18
    相关资源
    最近更新 更多