Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass current object type into base constructor call

How do I grab the Type of the inherited class and pass it into the base constructor of the class also inherited? See the code sample below:

// VeryBaseClass is in an external assembly
public abstract class VeryBaseClass
{
    public VeryBaseClass(string className, MyObject myObject)
    {

    }
}

// BaseClass and InheritedClass are in my assembly
public abstract class BaseClass : VeryBaseClass
{
    public BaseClass(MyObject myObject) :
        base(this.GetType().Name, myObject) // can't reference "this" (Type expected)
    {

    }
}

public class InheritedClass : BaseClass
{
    public InheritedClass(MyObject myObject)
    {

    }
}

The line base(typeof(this).Name, myObject) doesn't work because I can't reference this yet, as the object hasn't finished constructing and therefore doesn't exist.

Is it possible to grab the Type of the currently constructing object?

EDIT:

Corrected the sample as orsogufo suggested, but still doesn't work, as this is undefined.

EDIT 2:

Just to clarify, I want to end up with "InheritedClass" being passed into the VeryBaseClass(string className, MyObject myObject) constructor.

like image 363
Codesleuth Avatar asked Feb 18 '10 09:02

Codesleuth


2 Answers

Ah Hah! I found a solution. You can do it with generics:

public abstract class VeryBaseClass
{
    public VeryBaseClass(string className, MyObject myObject)
    {
        this.ClassName = className;
    }

    public string ClassName{ get; set; }
}
public abstract class BaseClass<T> : VeryBaseClass
{
    public BaseClass(MyObject myObject)
        : base(typeof(T).Name, myObject)
    {
    }
}

public class InheritedClass : BaseClass<InheritedClass>
{
    public InheritedClass(MyObject myObject) 
        : base(myObject)
    {

    }
}
like image 90
Thomas Avatar answered Sep 25 '22 20:09

Thomas


I've had exactly the same pain before now in the Google Wave Robot .NET API where I wanted to make the constructor pass in some values based on attributes. You can have a look at my solution in the code for the derived type and the base type. Basically I pass a delegate to the base constructor, and then call that delegate passing in "this" to the delegate. So in your case you'd have:

public VeryBaseClass(Func<VeryBaseClass, string> classNameProvider)
{
    this.name = classNameProvider(this);
}

and

public BaseClass() : base(FindClassName)
{
}

private static string FindClassName(VeryBaseClass @this)
{
    return @this.GetType().Name;
}

It's really ugly, but it works.

EDIT: This approach only works if you can change your base class constructor as shown; if you can't, I'm not sure it's actually feasible at all :(

like image 22
Jon Skeet Avatar answered Sep 25 '22 20:09

Jon Skeet