【发布时间】:2012-03-26 04:54:44
【问题描述】:
List<MyObject> a1 = new List<MyObject>();
var new1 = a1;
现在如果我更改a1,那么new1 也将被更改。
所以我的问题是如何正确地克隆 a1?
【问题讨论】:
标签: c# .net generics generic-list
List<MyObject> a1 = new List<MyObject>();
var new1 = a1;
现在如果我更改a1,那么new1 也将被更改。
所以我的问题是如何正确地克隆 a1?
【问题讨论】:
标签: c# .net generics generic-list
这不会Clone列表中的每个项目,但会为您创建一个新列表
var new1 = new List<MyObject>(a1);
如果你想克隆列表中的每个项目,你可以在MyObject上实现ICloneable
var new1 = new List<MyObject>(a1.Select(x => x.Clone()));
编辑:
为了更清楚一点,两者都会将列表 a1 中的元素复制到一个新列表中。您只需要决定是否要拥有新的MyObjects 或保留原件。如果你想克隆MyObject,你需要一种方法来克隆它们,这通常是通过ICloneable完成的。
【讨论】:
或者,你可以这样做:
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);
【讨论】:
我认为一般做法是避免使用Clone,因为不清楚它是对象的浅拷贝还是深拷贝。
更多关于这里: http://blogs.msdn.com/b/brada/archive/2004/05/03/125427.aspx
一个相当常见的解决方案是使用 BinaryFormatter 类来序列化/反序列化对象并返回新实例,但需要注意的是该类必须是可序列化的:
https://stackoverflow.com/a/1213649/1212407
假设以上,你可以这样做:
var clonedList = originaList.DeepClone();
【讨论】: