我在c#中有一个对象的通用列表,并希望克隆列表。列表中的项是可克隆的,但似乎没有做list. clone()的选项。
有什么简单的办法吗?
我在c#中有一个对象的通用列表,并希望克隆列表。列表中的项是可克隆的,但似乎没有做list. clone()的选项。
有什么简单的办法吗?
当前回答
没有必要将类标记为Serializable,在我们的测试中,使用Newtonsoft JsonSerializer甚至比使用BinaryFormatter更快。扩展方法可用于每个对象。
注意:私有成员不克隆
标准的。net JavascriptSerializer选项:
public static T DeepCopy<T>(this T value)
{
JavaScriptSerializer js = new JavaScriptSerializer();
string json = js.Serialize(value);
return js.Deserialize<T>(json);
}
使用Newtonsoft JSON更快的选项:
public static T DeepCopy<T>(this T value)
{
string json = JsonConvert.SerializeObject(value);
return JsonConvert.DeserializeObject<T>(json);
}
其他回答
对于浅拷贝,您可以使用泛型List类的GetRange方法。
List<int> oldList = new List<int>( );
// Populate oldList...
List<int> newList = oldList.GetRange(0, oldList.Count);
引用自:generic Recipes
如果你的元素是值类型,那么你可以这样做:
List<YourType> newList = new List<YourType>(oldList);
然而,如果它们是引用类型,并且你想要一个深度拷贝(假设你的元素正确地实现了ICloneable),你可以这样做:
List<ICloneable> oldList = new List<ICloneable>();
List<ICloneable> newList = new List<ICloneable>(oldList.Count);
oldList.ForEach((item) =>
{
newList.Add((ICloneable)item.Clone());
});
显然,要替换上面泛型中的ICloneable,并使用实现ICloneable的元素类型进行强制转换。
如果你的元素类型不支持ICloneable,但是有一个复制构造函数,你可以这样做:
List<YourType> oldList = new List<YourType>();
List<YourType> newList = new List<YourType>(oldList.Count);
oldList.ForEach((item)=>
{
newList.Add(new YourType(item));
});
就我个人而言,我会避免使用ICloneable,因为需要保证所有成员的深度副本。相反,我建议使用复制构造函数或类似YourType的工厂方法。CopyFrom(YourType itemToCopy)返回一个新的YourType实例。
这些选项中的任何一个都可以通过方法(扩展或其他方式)包装。
稍加修改后,你也可以克隆:
public static T DeepClone<T>(T obj)
{
T objResult;
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, obj);
ms.Position = 0;
objResult = (T)bf.Deserialize(ms);
}
return objResult;
}
public static Object CloneType(Object objtype)
{
Object lstfinal = new Object();
using (MemoryStream memStream = new MemoryStream())
{
BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
binaryFormatter.Serialize(memStream, objtype); memStream.Seek(0, SeekOrigin.Begin);
lstfinal = binaryFormatter.Deserialize(memStream);
}
return lstfinal;
}
public List<TEntity> Clone<TEntity>(List<TEntity> o1List) where TEntity : class , new()
{
List<TEntity> retList = new List<TEntity>();
try
{
Type sourceType = typeof(TEntity);
foreach(var o1 in o1List)
{
TEntity o2 = new TEntity();
foreach (PropertyInfo propInfo in (sourceType.GetProperties()))
{
var val = propInfo.GetValue(o1, null);
propInfo.SetValue(o2, val);
}
retList.Add(o2);
}
return retList;
}
catch
{
return retList;
}
}