Click here to Skip to main content
Click here to Skip to main content
Go to top

Constructing an instance class from its base class instance

, 8 Sep 2009
Rate this:
Please Sign up or sign in to vote.
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 Smile | :) 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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Yang Yu
Architect Prognex Corp.
Canada Canada
Love startups, programming, and machine learning.
 
CEO and Founder of FansFave.com
 
LinkedIn: http://www.linkedin.com/in/mryuyang
Twitter: http://twitter.com/mryangyu

Comments and Discussions

 
QuestionIn VB ? PinmemberBib3477015-Sep-09 10:31 
AnswerRe: In VB ? PinmemberYang Yu16-Sep-09 7:11 
GeneralRe: In VB ? PinmemberBib3477016-Sep-09 11:30 
GeneralRedundant Cast PinmemberRichard Deeming15-Sep-09 2:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 9 Sep 2009
Article Copyright 2009 by Yang Yu
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid