代码之家  ›  专栏  ›  技术社区  ›  Kishore Kumar

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

  •  13
  • Kishore Kumar  · 技术社区  · 15 年前

    我已经上课了 Employee 调用了3个属性 ID , Name , Dept . 我需要实施 Copy Clone 方法?当我使用 复制 克隆 方法我需要避免铸造?我该怎么做?.

    示例:与 DataTable 它正在 DataTable.Copy() DataTable.Clone() .

    6 回复  |  直到 13 年前
        1
  •  14
  •   Luke Girvin Nathan Bedford    14 年前

    您需要实现IClonable接口并为clone方法提供实现。 如果你想避免选角,就不要实现这个。

    一个简单的深度克隆方法可以是将对象序列化到内存,然后反序列化它。类中使用的所有自定义数据类型都需要使用[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 或者在Clone方法中将值赋给一个新对象。

        2
  •  3
  •   Tomas Jansson    15 年前

    您必须使用可克隆接口吗?如果您只有两个调用 Clone Copy 在通用接口中定义的?

    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框架中指定的对象对于这种情况非常复杂,您可以自己编写它。你还应该用 克隆 复制 ,也就是说,它们对你意味着什么?我知道有几个网站明确指出 克隆 是一个很深的拷贝 复制 是肤浅的复制品。

        3
  •  3
  •   Jon Hanna    15 年前

    你是说,如何实现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();
      }
    }
    
        4
  •  2
  •   Stefan P.    15 年前
        5
  •  2
  •   supercat    15 年前

    我经常看到复制构造函数被建议作为克隆方法的替代方法,但是除了使用密封类之外,行为是非常不同的。如果我有一个type Car,它只支持属性VIN、BodyColor和BodyStyle,还有一个派生类型FancyCar,它也支持内部结构和音响系统,那么接受一个type Car对象并使用Car copy构造函数复制它的代码最终将得到一个Car。如果FancyCar被传递到这样的代码中,那么产生的“复制品”将是一辆新车,它的车辆识别号、车身颜色和车身样式与原车匹配,但它将没有任何内饰结构或音响系统。相比之下,代码接受一辆车并对其使用克隆方法,将FancyCar传递给代码将导致产生FancyCar。

    除非要使用反射,否则任何克隆方法都必须在其基部调用base.MemberwiseClone。由于MemberwiseClone不是虚拟方法,我建议您定义一个受保护的虚拟克隆方法;您还可以通过定义具有相同名称的受保护作用域的虚拟嵌套类(因此,如果子类尝试调用base.MemberwiseClone,则不会将其解释为对伪类的无意义引用)。

        6
  •  2
  •   Liz Barraza    13 年前

    这里有一个例子:

    namespace XXX
    {
         [Serializable]
        public class ItemChecklist : ICloneable
        {
    
           // [...here properties, attributes, etc....]
    
    
    
            object ICloneable.Clone()
            {
                return this.Clone();
            }
            public ItemChecklist Clone()
            {
                return (ItemChecklist)this.MemberwiseClone();
            }
    
    
        }
    }
    

    i、 e如果使用此函数,则在“itemAdd”中会有对象“itemTemp”及其所有值的完整副本。

    ItemChecklist itemAdd = itemTemp.Clone();