如何在类中实现克隆和复制方法?

时间:2010-11-11 08:59:11

标签: c# casting copy clone

我的课程名为Employee,其中包含3个名为IDNameDept的属性。我需要实施CopyClone方法吗?当我使用CopyClone方法时,我需要避免使用Casting?我该怎么做?。

示例:与拥有DataTableDataTable.Copy()的{​​{1}}相同。

6 个答案:

答案 0 :(得分:14)

你需要实现IClonable接口并为克隆方法提供实现。如果你想避免强制转换,不要实现它。

一个简单的深度克隆方法可能是将对象序列化为内存然后反序列化。您的类中使用的所有自定义数据类型都需要使用[Serializable]属性进行序列化。对于克隆,您可以使用类似

的内容
  public MyClass Clone()
    {
        MemoryStream ms = new MemoryStream();
        BinaryFormatter bf = new BinaryFormatter();

        bf.Serialize(ms, this);

        ms.Position = 0;
        object obj = bf.Deserialize(ms);
        ms.Close();

        return obj as MyClass;
    }

如果您的班级只有value types,那么您可以使用copy constructor或只是将值分配给克隆方法中的新对象。

答案 1 :(得分:3)

您是否必须使用ICloneable接口,或者只是在通用接口中定义了两个名为CloneCopy的方法就足够了吗?

public class YourClass : ICloneable<YourClass>
{
    // Constructor logic should be here
    public YourClass Copy() { return this; }        
    public YourClass Clone() { return new YourClass(ID, Name, Dept); }
}

interface  IClonable<T>
{
    T Copy();
    T Clone();
}

或者我误解了什么?

我想说的是,你不必让它变得更复杂吗?如果您需要您的对象符合某些类型,您可以自己编写,如果.Net框架中指定的那个对于该情况是复杂的。您还应该使用CloneCopy来定义差异,也就是说,它们对您意味着什么?我知道有几个网站指定Clone是深层副本,而Copy是浅层副本。

答案 2 :(得分:3)

你的意思是,如何实现ICloneable.Clone()并让它返回类本身的类型。

public class MyType : ICloneable
{
  public MyType Clone() //called directly on MyType, returns MyType
  {
    return new MyType(/* class-dependant stuff goes here */);
  }
  object ICloneable.Clone() // called through ICloneable interface, returns object
  {
    return Clone();
  }
}

答案 3 :(得分:2)

答案 4 :(得分:2)

我经常看到复制构造函数被建议作为克隆方法的替代方法,但除了密封类之外,行为是非常不同的。如果我有一个类型Car,它只支持属性VIN,BodyColor和BodyStyle,以及衍生类型FancyCar,它也支持InteriorFabric和SoundSystem,那么接受Car类型对象并使用Car copy构造函数复制它的代码将结束一辆车。如果将FancyCar传递给此类代码,则生成的“复制”将是新的Car,其具有与原始汽车匹配的VIN,BodyColor和BodyStyle,但不具有任何InteriorFabric或SoundSystem。相比之下,代码接受Car并在其上使用克隆方法,将FancyCar传递给代码将导致生成FancyCar。

除非有人想使用Reflection,否则任何克隆方法都必须在其基础上调用base.MemberwiseClone。由于MemberwiseClone不是虚方法,我建议定义一个受保护的虚拟克隆方法;您可能还希望通过定义具有相同名称的受保护范围的虚拟嵌套类来阻止任何子类调用MemberwiseClone(因此,如果后代类尝试调用base.MemberwiseClone,则不会将其解释为对此无意义的引用虚拟课)。

答案 5 :(得分:2)

这是一个例子:

namespace XXX
{
     [Serializable]
    public class ItemChecklist : ICloneable
    {

       // [...here properties, attributes, etc....]



        object ICloneable.Clone()
        {
            return this.Clone();
        }
        public ItemChecklist Clone()
        {
            return (ItemChecklist)this.MemberwiseClone();
        }


    }
}

即使用此功能,您将在“itemAdd”中拥有对象“itemTemp”的完整副本及其所有值。

ItemChecklist itemAdd = itemTemp.Clone();