The specific question, why can't you do this:
public class MyGenericClass<T> : T
And you can do this:
public class MyGenericClass<T>
{
T obj;
}
The reason is that the CLR likes to be able to compile a single version of the code for MyGenericClass that will work for any reference type specified for T.
It can do this for the second case, because it can quietly replace T
with object
and insert appropriate casts, roughly equivalent to:
public class MyGenericClass
{
object obj;
}
But for the inheritance version, that trick doesn't work.
Also, many useful facilities would be impossible to describe through interface constraints. When you inherit from a type, you can do a lot more than just call methods on it - you can override them as well. Consider this hypothetical example:
class MyBase
{
public virtual void MyVirtual() { }
}
class MyGenericDerived<T> : T
{
public override void MyVirtual()
{
Console.WriteLine("Overridden!");
}
}
MyBase obj = new MyGenericDerived<MyBase>();
obj.MyVirtual();
What I want to do there is something like a "mix-in", where MyGenericDerived supplies definitions for virtual functions in whatever base it is applied to. But how does the compiler know that T will have a method called MyVirtual that can be overridden? I'd need to put a constraint on T. How would I express that through interfaces? It's impossible. Using interfaces to describe constraints isn't an adequate solution once you allow inheritance from type parameters. So that's another reason why it doesn't exist in the language today.