是否可以获取在某些程序集中用作通用类型参数的所有类型?
基本上,假设我有这个课程:
public class Foo<T>
{
T SomeProperty {get; set;}
}
现在,我有一个应用程序,在那里我可以通过某种方式使用上面的内容:
var stringFoo = new Foo<string>();
var intFoo = new Foo<int>();
假设这是Foo
使用的唯一位置。现在,我想获取Foo<string>
和Foo<int>
的类型定义。即我想找到在给定程序集中由通用类型定义(Foo<T>
)构造的所有类型。
那有可能吗?
答案 0 :(得分:1)
更正...仍然很痛苦...但是不需要额外的库。现在...在我的头顶上,有很多地方可以找到类型Foo<>
:
属性([MyAttribute(typeof(Foo<>)]
,或者Foo<>
本身就是Attribute
)
基本类型链(class MyClass : Foo<int>
)或如果Foo<>
是IFoo<>
则实现接口
一种类型的成员(字段,属性,事件,方法)(这里我只指那些签名部分,因此字段类型,方法参数和返回类型...)
< / li>一种类型的内部类型(另一种类型内部定义的类型)
所有这些都可以通过“简单”的反射应用程序找到。
最重要的是,您可以查看方法/属性的局部变量(最后是方法),事件(甚至最后是方法):如果您有MethodInfo method
,可以得到MethodBody body = method.GetMethodBody()
,而MethodBody
定义了LocalVariables
。
请注意,如果不反汇编代码(例如,使用Mono.Cecil),您将无法在
中检测到该代码。public class C
{
public List<int> MyList;
public void M()
{
MyList = new List<int>();
Console.WriteLine(new List<int>());
}
}
方法M
使用List<int>()
,因为没有使用类型List<int>
的局部变量。因此,最后您甚至需要分解所有方法。
很明显,每次您找到类型时,都必须检查该类型是Foo<>
,Foo<>
的子类还是使用Foo<>
作为参数({{1 }),或者是指针List<Foo<>>
,还是托管指针Foo<>*
或...)
答案 1 :(得分:1)
就变量而言,您可以通过检查方法来发现类型。
public static void GetGenericVariables()
{
//Declaring two variables here that use Foo<>
var inttype = new Foo<int>();
var stringType = new Foo<string>();
var methodInfo = typeof(ClassContainingMethod).GetMethod("GetGenericVariables");
var variables = methodInfo.GetMethodBody().LocalVariables;
foreach (var variable in variables)
{
if (variable.LocalType.IsGenericType && variable.LocalType.GetGenericTypeDefinition() == typeof(Foo<>))
{
Console.WriteLine(variable.LocalType.GenericTypeArguments[0].FullName);
}
}
}
输出:
System.Int32
System.String
尽管如此,您必须递归遍历程序集和类型。