Q:

How do generics implement structs?

I was thinking about this. classes are obviously passed around by ptr. I suspect structs are passed around by copying it but i don't know for sure. (it seems like a waste for an int array to have every element a ptr. and passing ptrs for ints)
But thinking about it, List<MyStruct> can not know the size of my struct. What happens when i do this? Are there multiple copies of "List`1" and every time i use it with a storage size it does not have it creates a new implementation? (adjusting for the new offsets of T and such). 
That could make sense since the source would be in the CIL inside of a DLL. But i am completely guessing, how is it done? Perhaps a reference or page # to the ECMA standards?

A:

Generics use the concept of open and closed generic types: A parametrized generic class definition (i.e. List<T>) is an open generic type of which the runtime generates a closed generic type for each different use you have in your code, i.e. a different type is created for List<int> and for List<MyStruct> - for each closed generic type the size and type of T is known at run-time.
Clarification from MSDN:

When a generic type or method is
  compiled into Microsoft intermediate
  language (MSIL), it contains metadata
  that identifies it as having type
  parameters. How the MSIL for a generic
  type is used differs based on whether
  the supplied type parameter is a value
  type or reference type.
When a generic type is first
  constructed with a value type as a
  parameter, the runtime creates a
  specialized generic type with the
  supplied parameter or parameters
  substituted in the appropriate
  locations in the MSIL. Specialized
  generic types are created one time for
  each unique value type that is used as
  a parameter.
Generics work somewhat differently for
  reference types. The first time a
  generic type is constructed with any
  reference type, the runtime creates a
  specialized generic type with object
  references substituted for the
  parameters in the MSIL. Then, every
  time that a constructed type is
  instantiated with a reference type as
  its parameter, regardless of what type
  it is, the runtime reuses the
  previously created specialized version
  of the generic type. This is possible
  because all references are the same
  size.

