In C#, nested types can be defined in generic classes just like they would be in non-generic classes. For example:

class G<T> {
  public class NestedC { }
  public enum NestedEnum { A, B }
}

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.

.class private auto ansi beforefieldinit G`1<T>
  extends [mscorlib]System.Object
{
  .class auto ansi nested public beforefieldinit NestedC<T>
    extends [mscorlib]System.Object
  {   ...

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:

class Test {
  static void Main() {
    Type type1 = typeof(G<int>.NestedC);
    Console.WriteLine(type1);
    Console.WriteLine(type1.IsGenericTypeDefinition);
 
    Type type2 = typeof(G<int>).GetNestedType("NestedC");
    Console.WriteLine(type2);
    Console.WriteLine(type2.IsGenericTypeDefinition);
  }
}

1. typeof(G<int>.NestedC) is translated by C# compiler to

  IL_0001:  ldtoken    class G`1/NestedC<int32>
  IL_0006:  call     class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)

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?

   G`1+NestedC[System.Int32]
   False
   G`1+NestedC[T]
   True

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:

.class private auto ansi beforefieldinit G`1<T>
  extends [mscorlib]System.Object
{
  .class auto ansi nested public beforefieldinit NestedNonGenericC
    extends [mscorlib]System.Object
  {  ...