我需要在.net 4.5(c#)中克隆对象(类,而不是struct)。 我找到了两种方法:
我喜欢拳头方式 - 它更容易,但我也找到Not Implpement ICloneable Interface,但它是非常老的帖子,在MSDN上我找不到这个界面已弃用。
有人说我,在.net 4.5中使用ICloneable是安全的吗?
答案 0 :(得分:3)
IClonable
只是一个接口,因此在您实现它之前 什么都没有。建议不使用IClonable
的帖子提到了原因:不清楚Clone
是实现为深层还是浅层副本。
所以只需提供Copy
或DeepClone
方法,每个人都知道会发生什么。
引用解释这两个术语:
实现ICloneable有两种常规方法,可以是深, 或非深副本。深层复制复制克隆的对象和所有对象 由对象引用,递归地直到图中的所有对象 被复制。非深拷贝(如果只是顶部,则称为浅) 复制级别引用)可以不执行任何操作,也可以是深层复制的一部分。
答案 1 :(得分:1)
您不应使用IClonable接口。
几年前的Here's a blog from Brad Abrams discussing why not。基本上,Tim Schmelter的答案概述了原因,但是这篇博客来自马的嘴。
关于通过序列化实现克隆,现在有一种更好的方法可用,因为我们可以指定StreamingContextStates.Clone
以使克隆能够更好地处理非托管句柄等事情。
Jeffrey Richter的“CLR via C#4th Edition”中有一个规范的实现,如下所示:
public static object DeepClone(object original)
{
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter
{
Context = new StreamingContext(StreamingContextStates.Clone)
};
formatter.Serialize(stream, original);
stream.Position = 0;
return formatter.Deserialize(stream);
}
}
或强类型变体:
public static T DeepClone<T>(T original)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "original");
}
if (ReferenceEquals(original, null))
{
return default(T);
}
using (var stream = new MemoryStream())
{
var formatter = new BinaryFormatter
{
Context = new StreamingContext(StreamingContextStates.Clone)
};
formatter.Serialize(stream, original);
stream.Position = 0;
return (T) formatter.Deserialize(stream);
}
}
我认为你应该(尽可能)使用它而不是实现IClonable
。