Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# inheritance. Derived class from Base class

I have a base class

public class A   
{
    public string s1;
    public string s2;
}

I also have a derived class :

public class B : A
{
    public string s3;
}

Suppose my program created an instance of class A.

A aClassInstance = new A();

some parameters were set:

aClassInstance.s1 = "string 1";
aClassInstance.s2 = "string 2";

At this point I would like to create an instance of class B. But I would like B to already have the values of my instance of class A.

This DID NOT Work:

public B bClassInstance = new B():
bClassInstance = (B)aClassInstance;

NEITHER DID THIS:

Made a clone method within Class A.

public B cloneA() {    
    A a = new A();
    a = (A)this.MemberwiseClone()
    return(B)a;
}

The VS code takes both of the above - but I get run-time errors

Please help

like image 410
Sam Avatar asked Dec 25 '11 22:12

Sam


2 Answers

The base problem you have is, that you have to construct an instance of type B (which contains of cause the properties of type A). Your approach to clone an A instance won't work, because that gives you an instance of type A, which you can't convert to B.

I would write constructors for class A and B which takes a parameter of type A. The constructor of class B just passes the value to its base class A. The constructor of class A knows how to copy the fields to itself:

class A {
    public A(A copyMe) {
        s1 = copyMe.s1;
        ...
    }

class B : A {

    public B(A aInstance) : base(aInstance) {
    }

}

Use it this way:

A a = new A();
a.s1 = "...";

B b = new B(a);

EDIT

When you don't want to have to change the constructor of A when adding new fields or props, you could use reflection to copy the properties. Either use a custom attribute to decorate what you want to copy, or copy just all props/fields of A:

public A (A copyMe) {
    Type t = copyMe.GetType();
    foreach (FieldInfo fieldInf in t.GetFields())
    {
        fieldInf.SetValue(this, fieldInf.GetValue(copyMe));
    }
    foreach (PropertyInfo propInf in t.GetProperties())
    {
        propInf.SetValue(this, propInf.GetValue(copyMe));
    }
}

I havn't tried the code, but the point should become clear.

like image 143
Jan Avatar answered Sep 22 '22 11:09

Jan


You could create a generic clone method in class A:

     public T Clone<T>() where T : A, new() {
          return new T() { a = this.a, b = this.b};
     }

Or if you want to make the cloning extendable:

     public T Clone<T>() where T : A, new() {
          var result = new T();
          this.CopyTo(result);
          return result;
     }

     protected virtual void CopyTo(A other) {
          other.a = this.a;
          other.b = this.b;
     }

You use it like this:

     A  a = new A();
     // do stuff with a
     // Create a B based on A:
     B b = a.Clone<B>();

Please note: in your example, both the new A(), and the MemberwiseClone will create a new object of type A.

If you do not want to code the copy method yourself, you could look at a tool like AutoMapper.

like image 20
GvS Avatar answered Sep 20 '22 11:09

GvS