Can the type of the current class be used as the value of a generic type parameter?

Can something like this be accomplished using C#?

public abstract class BaseClass
{
    public abstract IInterface<T> CreateEditor() where T: the_actual_type_of_this_instance;
}

Example usage:

var instance = new DerivedClass();
var editor = instance.CreateEditor(); // IInterface<DerivedClass>
Jon Skeet
people
quotationmark

No, you can't do that - partly because it wouldn't make sense at compile time. Consider a slight change to your code:

BaseClass instance = new DerivedClass();
var editor = instance.CreateEditor();

What could the compiler infer the type of editor to be? It only knows about BaseClass, so it would have to return an IInterface<BaseClass>. Depending on whether or not T in IInterface<T> is covariant, that could be valid for something which actually implemented IInterface<DerivedClass> or it might not be.

You might want to make your base class generic instead:

public abstract class BaseClass<T> where T : BaseClass<T>
{
    public abstract IInterface<T> CreateEditor();
}

public class DerivedClass : BaseClass<DerivedClass>
{
    ...
}

There are two problems with this:

  • It doesn't work when you go more than one level deep; if you need subclasses of DerivedClass, you'll have issues
  • It doesn't prevent malicious abuse of the pattern, e.g. public class NastyClass : BaseClass<DerivedClass>

... but in many cases it's quite practical.

people

See more on this question at Stackoverflow