c#中的对象克隆

时间:2012-03-15 21:56:37

标签: c# object clone

请考虑以下相关问题:Deep cloning objects

这真的是克隆对象的最佳方法吗?化(serialize /反序列化)。序列化对我来说似乎有点贵。

我的想法是创建第二个构造函数并只分配所有变量。这种方法会更快吗?

class Test
{

public Test(Test clone)
{
// clone ....
}
}

6 个答案:

答案 0 :(得分:6)

这取决于你想要克隆什么以及为什么。如果浅克隆是好的,那么:

private static T CloneShallow<T>(T i) {
    return
        (T)i.GetType()
            .GetMethod(
                "MemberwiseClone",
                BindingFlags.Instance | BindingFlags.NonPublic
            ).Invoke(i, null);
}

这是克隆任何类型简单记录的最快方法。

如果您需要完整副本,但这不是时间关键,那么:

private static T CloneFull<T>(T i) {
    if (Object.ReferenceEquals(i, null)) return default(T);
    var x = new XmlSerializer(i.GetType());
    using (var m = new MemoryStream()) {
        x.Serialize(m, i);
        m.Seek(0, SeekOrigin.Begin);
        return (T)x.Deserialize(m);
    }
}

第二个比第一个慢约70倍。

如果您需要完整副本并且速度很重要,请考虑使用protobuf-net作为序列化程序。

有许多答案涉及修改你想要克隆的对象,但通常你只需要克隆一个简单的记录,而你不想在它上面实现任何东西。

如果你想知道CloneFull()的速度有多慢 - 在我的电脑(i5 661 @ 3.33GHz)上有非常简单的记录,它需要360个刻度,这会产生36ns。在大多数情况下,这是足够快的:)

答案 1 :(得分:2)

关键词位于accepted answer

  

好处是,当对象过于复杂时,您不必担心克隆所有内容。

序列化方法适用于任何复杂的任何对象。虽然对于更小,更简单的对象来说可能是过度杀伤,但它是一种可扩展的解决方案。

如果您知道您的对象不会改变,并且您只想克隆简单对象,那么您的方法是完全可以接受的。虽然实现ICloneable接口是首选解决方案。

答案 2 :(得分:2)

您所引用的问题涉及泛型克隆,它适用于支持序列化的任何内容。如果只想为特定的对象进行克隆,只需实现ICloneable

class Test : ICloneable {
    public object Clone() {
        // clone ....
    }
}

答案 3 :(得分:1)

序列化仅 对于存储要在以后/其他地方检索的对象的表示特别有用。如果您希望对象能够克隆,则应该实现ICloneable接口。

答案 4 :(得分:1)

ICloneable

引用:

支持克隆,它创建一个具有与现有实例相同值的类的新实例。 ICloneable接口包含一个成员Clone,用于支持ClientwiseClone提供的克隆。有关克隆,深拷贝和浅拷贝以及示例的详细信息,请参阅Object.MemberwiseClone方法。

答案 5 :(得分:1)

如果您正在谈论使用自定义类,最好的方法是实现ICloneable。通过这种方式,您的课程可以提供克隆自身的标准化方法。

有时候使用“复制构造函数”可能会更好,但通常只有在您看到它很简单的情况下,ICloneable才能充分满足您的需求。