Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Constructing an instance class from its base class instance

0.00/5 (No votes)
8 Sep 2009 1  
A Generic way to construct an instance of a class from an instance of its base class.

Introduction

This is a simple solution for a simple problem. There will not be any code attachments for this reason. Copy and paste and you're good to go :) On the same note, I will try not just copy and paste code here and hit the big green button. So bare with me just a tiny bit.

Basically...

.NET allows you to cast from an instance of a class of type T to its base class F with ease.

Example

Given the classes Male: Person: Animal:

class Animal 
{
    private int _age;
    public int Age
    {
        get { return this._age; }
        set { this._age = value; }
    }

}

class Person: Animal
{
    private string _codeProjectName;
    public string CodeProjectName
    {
        get { return this._codeProjectName; }
        set { this._codeProjectName = value; }
    }

}

class Male: Person
{
    private long _ego;
    public long Ego
    {
        get { return this._ego; }
        set { this._ego = value; }
    }
}

We can simply cast a Male object to a Person or Animal, like so:

...
 Person yang = new Person();
 Animal AlsoYang = (Animal)yang; // note: same memory address different pointer
...

Problem...

Time to time again, I've always had to deal with the problem of wanting to create an instance of a class of type T derived from an instance of its base class type F. (I am implying that I want to copy the Data Model, specifically properties.) Usually, I will simply create a custom constructor or write some hard-coded logic to implement this functionality.

So to do this, we will use Generics, and Reflection.

Like so...

/// <summary>
/// construct a derived class of from a base class
/// </summary>
/// <typeparam name="F">type of base class</typeparam>
/// <typeparam name="T">type of class you want</typeparam>
/// <param name="Base">the instance of the base class</param>
/// <returns></returns>
public static T Construct<F, T>(F Base) where T : F, new()
{
    // create derived instance
    T derived = new T();
    // get all base class properties
    PropertyInfo[] properties = typeof(F).GetProperties();
    foreach (PropertyInfo bp in properties)
    {
        // get derived matching property
        PropertyInfo dp = typeof(T).GetProperty(bp.Name, bp.PropertyType);

        // this property must not be index property
        if (
            (dp != null)
            && (dp.GetSetMethod() != null)
            && (bp.GetIndexParameters().Length == 0)
            && (dp.GetIndexParameters().Length == 0)
        )
            dp.SetValue(derived, dp.GetValue(Base,null), null);
    }

    return derived;
}

Notice that the generic type clause states that T: F, which means that T must be a subclass of F and contains all of the public and private properties of F. (Again, this implementation deals with properties. If you want variables, be my guest.)

Note: In the above code, we are not cloning the property values, so changing the value of the derived instance will change the base instance since they are from the same pointer.

Using the darn thing...

Using the above example, we can get a new instance of a derived class of Animal such as a Person.

...
Animal yang_ox = new Animal();
yang_ox.Age = 10;
Person yang = Construct<Animal, Person>(yang_ox);
// note: this is a new instance with shallow property values
 
// guess what yang.Age is?? yup its 10. Easy
...

Further thinking...

Using this approach, one can also address a similar solution for Cloning<T>(), and even Construct<F,T> where F:T.

One could also go even further with this and do some assembly injection compiled code at run time to save all this Reflection jazz.

Hope you enjoyed the short read. Hopefully I won't get any 1s. Fingers are crossed. ^_^

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here