Why can't the compiler detect what T really does, because (practically) T: TBase: class?
Because it is simply not true. In addition to what Poke points out in the response, this is also illegal because all types of values ββinherit from object :
var dc = new DemoClass<object>(); dc.DemoMethod(1);
Your reasoning just falls apart when value types are involved. Frivolous? Yes, but completely legal, so the compiler has no choice and should consider your code illegal.
UPDATE
Addressing John Hana's comment below, that in the above code T is not actually int , its object and 1 placed in the box implicitly, which is absolutely wrong. Consider the following variation of DemoMethod :
public T DemoMethod<T>(T target) where T : TBase { return target; }
And the following code:
var dc = new DemoClass<object>(); var i = dc.DemoMethod(1);
i is int , its not an object . In addition, the following will be executed correctly:
long i = dc.DemoMethod(1);
Which also proves that T cannot be placed in an int box, because the implicit conversion will fail at runtime; you cannot unpack a value type for anything but the type itself.
And, of course, you can always explicitly specify T , which also just compiles:
dc.DemoMethod<int>(1);
source share