docs/design/mono/web/generics.md
Type/Method instantiation == Type/Method instance == Inflated Type/Method.
These are represented by a normal MonoClass structure with the generic_container field set. This field points to a MonoGenericContainer structure, which stores information about the generic parameters of the generic type.
These are represented by a pair of MonoGenericClass and MonoClass structures. The generic_class field in MonoClass is used to link the two together. The reason for the split is to avoid allocating a large MonoClass if not needed.
It would have been better to name MonoGenericClass MonoInflatedClass or something similar.
These are represented by a MonoMethod structure with the is_generic field set to 1.
These are represented by a MonoMethodInflated structure, which is an extension of the MonoMethod structure. Its is_inflated field is set to 1.
One consequence of this design is that a method cannot be a pinvoke method/wrapper/dynamic method and an inflated method at the same time.
This structure holds information of an instantiation of a set of generic parameters with generic arguments. It is used by both type and method instatiations.
The runtime canonizes generic type/method instances, so for every set of generic arguments, there is only one type/method instance with those arguments. This is using caches in metadata.c.
Inflated types and methods depend on the assembly of the generic type/method definition they are inflated from, along with the assemblies of their generic arguments. This is handled using the concept of 'image sets' in metadata.c. Every inflated type/method belongs to an image set, which is a set of MonoImages. When one of the assemblies in an image set is unloaded, all the inflated types/methods belonging to the image set are freed. Memory for inflated types/methods cannot be allocated from mempools, it is allocated from the heap. The mono_class_alloc/alloc0 functions can be used to allocate memory from the appropriate place.
Generics support in System.Reflection.Emit (SRE) is very problematic because it is possible to create generic instances of not yet created dynamic types, i.e. if T is a generic TypeBuilder, it is possible to create T<int>. The latter is not a TypeBuilder any more, but a normal Type, which presents several problems:
These problems are currently handled by a hierarchy of C# classes which inherit from the normal reflection classes:
MonoGenericClass represents an instantiation of a generic TypeBuilder. MS.NET calls this TypeBuilderInstantiation, a much better name.Method/Field/Event/PropertyOnTypeBuilderInst represents a method/field etc. of a MonoGenericClass.