Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will memberwiseclone also copy members defined in derived class?

Tags:

c#

clone

copy

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();
    }
}
like image 293
Jeffrey Goines Avatar asked Jun 16 '14 02:06

Jeffrey Goines


1 Answers

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.

like image 86
EKrueger Avatar answered Oct 21 '22 21:10

EKrueger