10

I need to define a Clone() method that does shallow copy. (No deep copy needed)

But I need that to copy derived class' members of as well.

If I had

class Base {
     int baseMember;
     public (virtual?) Base Clone() {
         return (Base)this.MemberwiseClone()
     }
}

then should I derive all other classes for Clone()? Will derivedMember also be copied by Base.Clone()?

class Derived {
    int derivedMember;  //will this also be copied by base.Clone()?

    //Necessary?
    public new Derived (override Base?) Clone() {
        return (Derived)this.MemberwiseClone();
    }
}
JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Jeffrey Goines
  • 935
  • 1
  • 11
  • 30
  • `MemberwiseClone()` is the same function no matter which function you call it from. – SLaks Jun 16 '14 at 02:45
  • well since `Clone` returns `Base` its wont include anything from `Derived`, may be better to implement `IClonable` and return `object` from your clone method – sa_ddam213 Jun 16 '14 at 03:11

1 Answers1

9

Will derived (nonstatic) fields also be copied when calling this.MemberwiseClone() on its base class?

Yes, they will as you can assure yourself by writing a little test like this one:

private static void Main(string[] args)
{
    Student a = new Student() { Name = "John Doe", Id = 1 };
    Student b = (Student)a.Clone();
}

public class Person
{
    public string Name { get; set; }

    public virtual Person Clone()
    {
        return (Person)this.MemberwiseClone();
    }
}

public class Student:Person
{
    public int Id { get; set; }
}

Additionally this question was already answered here.

Do I need to override (or rewrite) the Clone method in the derived class?

Technically it's not necessary, but as you see you have to cast the result since the return type of the base.Clone() method is Person.

Alternatively you could rewrite your base class Clone() method like this:

public T Clone<T>() where T:Person
{
    return (T)this.MemberwiseClone();
}

Then you need to call

Student b = a.Clone<Student>();

on your derived classes. So you only have to write the clone method once in the base class. Although I'm not sure if this is the best solution.

Community
  • 1
  • 1
EKrueger
  • 730
  • 8
  • 20
  • 1
    Expounding upon this answer, another option to reduce the need to pass the generic on the method is to update the base class to provide your sub-class. `public class Person { ... }` and `public class Student : Person { ... }`. Then subclasses can just call `.Clone()` – wintondeshong Mar 08 '21 at 11:49