nuclear sweet
nuclear sweet

Reputation: 1121

MemberwiseClone vs new object

I got:

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
    }
}

How should i implement Clone() in this objects? I need to make deep clone as far as i need this objects as DTO in different tasks.

Should i make it like (for 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; 
}

And for B same way, or there is different good pattern / solution? Should i use new object() instead of MemberwiseClone() and manually set fields? Thanks.

Upvotes: 3

Views: 965

Answers (1)

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186803

You can do it like that:

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; 
    }
}

Upvotes: 2

Related Questions