当我列出当前AppDomain中的所有类型时,我会看到带有通用占位符的泛型类型。但是,如果我使用类型实例化我的泛型类型然后列出appDomain中的所有类型,我看不到新创建的封闭类型。
在下面的示例中,输出仅为:
Foo`1[T]
我正在寻找封闭式:
Foo`1[System.Int32]
有没有办法根据我的开放泛型类型查看运行时为我创建的封闭类型?
class Foo<T>
{
}
class Program
{
static void Main(string[] args)
{
var tmp = new Foo<int>();
ListTypes();
}
private static void ListTypes()
{
var types = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.Name.Contains("Foo")
select type;
foreach (var type in types)
Console.WriteLine(type.ToString());
}
}
我还尝试通过泛型参数查找所有类型,以期发现封闭类型。
class Foo<T>
{
}
class Bar
{
}
class Program
{
static void Main(string[] args)
{
var tmp = new Foo<Bar>();
ListTypes();
}
private static void ListTypes()
{
var types = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
where type.IsGenericType
&& type.GetGenericArguments().Contains(typeof(Bar))
select type;
foreach (var type in types)
Console.WriteLine(type.ToString());
}
}
这只是为了满足我的好奇心。
答案 0 :(得分:1)
Ivan的答案大多是正确的,但声称程序集元数据不包含任何有关构造类型的信息并不完全正确。所有构造的类型都在使用它们的程序集中定义,而 Mono.Cecil 等工具让您可以看到它。构造的类型不会通过反射暴露,甚至Mono.Cecil也很难找到它们。
基本上,您必须遍历程序集中使用的所有类型,例如:属性类型,返回类型,局部变量类型等。此信息包含在程序集元数据中,并且使用Mono.Cecil相当容易枚举。然后只应用简单的过滤器来检测是否构造了类型。请注意,您可能需要遍历几个引用泛型类型定义的程序集,以便查找从中构造的所有类型。
此解决方案有两个限制。首先,通过反射构造的类型自然不会出现在任何组件中。其次,一些构造类型嵌入在泛型类型/方法中,并且只有在使用特定泛型类型参数实例化其父类型/方法之后,才能知道它们的泛型类型参数。