.NET:为什么嵌套类具有在外部类中声明的泛型?

时间:2019-02-22 14:56:24

标签: c# .net cil

因为Type.FullName有点丑陋,所以我需要创建漂亮的名称构造函数。但是当我使用Type.GetGenericArguments()时遇到一个问题。

外部类T的泛型C1始终分配给嵌套类C2C3

class C1<T> {
    public class C2<T1, T2> {
    }
    public class C3 {
    }
}

typeof( C1<> ).ToString(); // C1`1[T]
typeof( C1<>.C2<,> ).ToString(); // C1`1+C2`2[T,T1,T2]
typeof( C1<>.C3 ).ToString(); // C1`1+C3[T]

两个问题:

  • 如何确定泛型类型是否来自外部类?
  • 这种行为的原因是什么?

1 个答案:

答案 0 :(得分:-1)

类型参数不是CIL中的嵌套类“继承”的。在那里,您的班级看起来像这样:

.class private auto ansi beforefieldinit C1`1<T> extends [mscorlib]System.Object
{
    .class nested public auto ansi beforefieldinit C2`2<T, T1, T2> extends [mscorlib]System.Object
    {
    }

    .class nested public auto ansi beforefieldinit C3<T> extends [mscorlib]System.Object
    {
    }
}

由于嵌套类型的定义实际上并不依赖于父类型,因此外部通用参数不需要对其进行访问,因此决定必须像C#一样显式地重复它们,但是支持以不同方式工作的语言(其中C1<>.C3是具体类型)。

那么您的问题是从.NET类型获取C#类型表达式之一。您可能对CodeDOM感到很幸运,或者只是假设嵌套类型的通用参数与父类型的通用名称相同,则可以在创建字符串时将其省略。

因此,重申一下,泛型参数不能来自.NET中的外部类,而仅仅是C#的行为。如果假定该类是用C#创建的,则可以根据其名称简单地删除参数。