创建对象的副本



我需要在。net 4.5 (c#)中克隆对象(类,而不是结构)。
我找到了两种方法:

  1. 实现iclonable Interface
  2. 创建自己的克隆机制,就像这个著名的SO答案

我喜欢第一种方式-它更容易,但我也发现了不实现iclonable接口,但它是非常旧的帖子,在MSDN上我找不到这个接口弃用。

有人能告诉我,在。net 4.5中使用iclonable是安全的吗?

IClonable只是一个接口,所以在您实现它之前,它不做任何事情。建议不使用IClonable的帖子提到了原因:不清楚Clone是作为深拷贝还是浅拷贝实现的。

所以只要提供一个CopyDeepClone方法,每个人都知道会发生什么。

引用来解释这两个术语:

有两种实现iclonable的一般方法,要么作为深度,或者非深度拷贝。深拷贝对克隆对象和所有对象进行拷贝由对象引用,递归地直到图中的所有对象被复制。如果只是顶部,则非深拷贝(称为浅拷贝级别引用被复制)可以不做任何操作,或者是深度复制的一部分。

你不应该使用IClonable接口。

这是Brad Abrams几年前写的一篇关于为什么不写的博客。基本上,蒂姆·施梅尔特的回答概述了原因,但这篇博客是来自马的嘴。

关于通过序列化实现克隆,现在有一个稍微好一点的方法可用,因为我们可以指定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

相关内容

  • 没有找到相关文章

最新更新