Search code examples
c#genericstype-parametergeneric-constraints

Base class constraint on generic class specifying the class itself


Yesterday, I was explaining C#'s generic constraints to my friends. When demonstrating the where T : CLASSNAME constraint, I whipped up something like this:

public class UnusableClass<T> where T : UnusableClass<T>
{
    public static int method(T input){
        return 0;
    }
}

And was really surprised to see it compile. After a bit of thinking, however, I figured it was perfectly legal from the point of view of the compiler - UnusableClass<T> is as much of a class as any other that can be used in this constraint.

However, that leaves a couple of questions: how can this class ever be used? Is it possible to

  1. Instantiate it?
  2. Inherit from it?
  3. Call its static method int method?

And, if yes, how?

If any of these is possible, what would the type of T be?


Solution

  • Well.

    public class Implementation : UnusableClass<Implementation>
    {
    }
    

    is perfectly valid, and as such makes

    var unusable = new UnusableClass<Implementation>();
    

    and

    UnusableClass<Implementation>.method(new Implementation());
    

    valid.

    So, yes, it can be instantiated by supplying an inheriting type as the type parameter, and similarly with the call to the static method. It's for instance useful for tree-like structures where you want to generically specify the type of children the node has, while it being the same type itself.