Question

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?

Was it helpful?

Solution

Contrary to another answer, there are types beyond T=System.Object where this compiles:

class Samplewhere T:class where U:struct, T

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.ValueType or System.Enum (which derives from System.ValueType) and that's picked on the basis of whether you're declaring a struct or an enum. It's somewhat confusing that both of these are, themselves, reference types...

OTHER TIPS

All structs derive from the ValueType type implicitly. You cannot specify an explicit base type.
Refer to this MSDN tutorial on structs as posted by codemelt.

  • When you instantiate a struct e.g. as a local variable, they are allocated on the stack (better performance)
  • Classes may contain structs as members - in which case they are allocated on the heap.

MSDN says,

There is no inheritance for structs as there is for classes. A struct cannot inherit from another struct or class, and it cannot be the base of a class. Structs, however, inherit from the base class object. A struct can implement interfaces, and it does that exactly as classes do.

Sasha Wrote:

If there is no inheritance allowed, then why is the following legal:

class Samplewhere T:class where U:struct, T

In the case above, parameter U is value type, and it derives from T -- reference type

Although that's legal from a generic contract standpoint, you'll never get any useful code that uses that class to compile, because you'll never have a type other than T=System.Object that fulfills the U constraint. You might consider that a very minor bug in the implementation of generics in C#.

Structs cannot inherit from anything other than System.ValueType or System.Enum. There is no way a struct can inherit from a normal reference type. So unfortunately this question cannot be answered.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top