I saw the following line of code:
class Sample<T,U> where T:class where U: struct, T
In the case above, parameter U is value type, and it derives from reference type T.
How can that line be legal?
Also, if a value type inherits from a reference type, where is memory allocated: heap or stack?
Contrary to another answer, there are types beyond T=System.Object where this compiles:
The ‘T : class’ constraint doesn’t actually mean that T has to be a class. It means T has to be a reference type. That includes interfaces, and structs can implement interfaces. So, for example, T=IConvertible, U=System.Int32 works perfectly well.
I can’t imagine this is a particularly common or useful constraint, but it’s not quite as counterintuitive as it seems at first sight.
As to the more general point: as Obiwan Kenobi says, it all depends on your point of view. The CLI spec has quite a complicated explanation of this, where ‘derives from’ and ‘inherits from’ don’t mean quite the same thing, IIRC. But no, you can’t specify the base type of a value type – it’s always either
System.ValueTypeorSystem.Enum(which derives fromSystem.ValueType) and that’s picked on the basis of whether you’re declaring astructor anenum. It’s somewhat confusing that both of these are, themselves, reference types…