MemberwiseClone与新对象

时间:2014-05-07 10:38:25

标签: c# .net c#-4.0 clone

我得到了:

internal sealed class A : ICloneable
{
    public Collection<B> CollectionB { get; set; }

    public int Int1 { get; set; }
    public int Int2 { get; set; }
    public int Int3 { get; set; }
    public int Int4 { get; set; }
    //. . .
    //some different value types, lets think all of type int for simplyfy

    public object Clone()
    {
        //Need to implement Clone
    }

}


internal sealed class B : ICloneable
{
    public Collection<Bitmap> SomeBitmaps { get; set; }

    public int Int1 { get; set; }
    public int Int2 { get; set; }
    //. . .
    //etc.

    public object Clone()
    {
        //same as class A
    }
}

我应该如何在这个对象中实现Clone()? 我需要进行深度克隆,因为在不同的任务中我需要这个对象作为DTO。

我应该这样做(对于A):

public object Clone()
{
     var clone = this.MemberwiseClone();
     var cloneCollectionB = new Collection<B>();
     foreach(var element in CollectionB)
     {
          cloneCollectionB.Add(((B)element).Clone());
     } 
     ((A)clone).CollectionB = cloneCollectionB;
     return clone; 
}

对于B同样的方式,还是有不同的好模式/解决方案?我应该使用new object()代替MemberwiseClone()并手动设置字段吗?感谢。

1 个答案:

答案 0 :(得分:2)

你可以这样做:

internal sealed class A: ICloneable {
  // Let it be List, OK?
  // It looks, that you don't need "set" here 
  public List<B> CollectionB { get; }

  public int Int1 { get; set; }
  public int Int2 { get; set; }
  public int Int3 { get; set; }
  public int Int4 { get; set; }

  // It's more convenient to return A, not Object
  // That's why explicit interface implementation    
  Object ICloneable.Clone() {
    return this.Clone();
  }

  public A Clone() {
    A result = new A();

    result.Int1 = Int1; 
    result.Int2 = Int2; 
    result.Int3 = Int3; 
    result.Int4 = Int4; 

    // Deep copy: you have to clone each B instance:
    foreach(B item in CollectionB)
      result.CollectionB.Add(item.Clone()); // <- thanks for explicit inteface impl. it ret B

    return result;
  }
}

internal sealed class B: ICloneable {
    // Let it be List
    // It looks, that you don't need "set" here 
    public List<Bitmap> SomeBitmaps { get; }

    public int Int1 { get; set; }
    public int Int2 { get; set; }
    //. . .
    //etc.

    // It's more convenient to return B, not Object
    // That's why explicit interface implementation    
    Object ICloneable.Clone() {
      return this.Clone();
    }

    // It's more convenient to return B, not Object    
    public B Clone() {
      B result = new B();

      result.Int1 = Int1; 
      result.Int2 = Int2; 
      // ...
      //etc.

      // Deep copy: you have to create new bitmaps here
      foreach(Bitmap source in SomeBitmaps) 
        result.SomeBitmaps.Add(new Bitmap(source));

      return result; 
    }
}