In C#, nested types can be defined in generic classes just like they would be in
non-generic classes. For example:
Inside the nested type NestedC, we can still use type parameter T, which was "declared"
with class G<T>. Actually this is a misconception (the C# compiler does some
magic behind the scenes). If we were to use ildasm to view the node of NestedC,
we would find "NestedC" is a generic type with type parameter "T". As far as the
runtime is concerned, this "T" is not the same as the "T" with G<T>; they
just happen to have the same name.
When we use T inside NestedC, we are in fact referring to NestedC's own T, the type
parameter "T" declared with NestedC<T>. With that in mind, let us think about
what the following code will print:
1. typeof(G<int>.NestedC) is translated by C# compiler to
The generic argument "int32" is bound to NestedC<>, not G<>;
2. You might already have noticed that although both are generic types, "NestedC"
does not have `(grave accent), but "G`1" does. So typeof(G<int>).GetNestedType("NestedC")
will get back the open generic type "NestedC<>".
Here is the result, is it as you expected?
In summary, when written in C#, every type defined under a generic type will be
a generic type (including enum; C# does not allow us to explicitly define a generic
enum). To define a truly non-generic nested type inside a generic type, IL can help: