When a generic class is compiled, there is actually nothing different between it and a regular class. Indeed, the result of the compilation is nothing but metadata and intermediate language (IL). The IL is, of course, parameterized to accept a user-supplied type somewhere in code. How the IL for a generic type is used differs based on whether or not the supplied type parameter is a value or reference type.
When a generic type is first constructed with a value type as a parameter, the run-time creates a specialized generic type with the supplied parameter (or parameters) substituted in the appropriate places in the IL. Specialized generic types are created once for each unique value type used as a parameter.