[英]Get all types that are used as generic type arguments
Is it possible to get all types that are used as generic type arguments within certain assembly? 是否可以获取在某些程序集中用作通用类型参数的所有类型?
Basically, imagine I have this class: 基本上,假设我有这个课程:
public class Foo<T>
{
T SomeProperty {get; set;}
}
Now, I have an application and there I use the above in some way: 现在,我有一个应用程序,在这里我可以通过某种方式使用上面的代码:
var stringFoo = new Foo<string>();
var intFoo = new Foo<int>();
Assume this is the only place the Foo
is used. 假设这是
Foo
使用的唯一位置。 Now I would like to get type definitions of Foo<string>
and Foo<int>
. 现在,我想获取
Foo<string>
和Foo<int>
类型定义。 Ie I want to find all types that are constructed from generic type definition ( Foo<T>
) within given assembly. 即我想找到在给定程序
Foo<T>
由通用类型定义( Foo<T>
)构造的所有类型。
Is that even possible? 那有可能吗?
Correction... Still a pain... But no extra libraries needed. 更正...仍然很痛苦...但是不需要额外的库。 Now... On top of my head there are various places where you could find a type
Foo<>
: 现在...在我的头顶上,有很多地方可以找到类型
Foo<>
:
attributes ( [MyAttribute(typeof(Foo<>)]
, or perhaps Foo<>
is in itself an Attribute
) 属性(
[MyAttribute(typeof(Foo<>)]
或Foo<>
本身就是Attribute
)
base type chain ( class MyClass : Foo<int>
) or if Foo<>
is a IFoo<>
then implemented interfaces 基本类型链(
class MyClass : Foo<int>
),或者如果Foo<>
是IFoo<>
则实现接口
members of a type (fields, properties, events, methods) (here I mean only the signature part of those, so the field type, the method arguments and return type...) 类型的成员(字段,属性,事件,方法)(这里我仅指那些签名部分,因此字段类型,方法参数和返回类型...)
inner types of a type (types defined inside another type) 一个类型的内部类型(在另一个类型内部定义的类型)
All of these can be found with "simple" application of reflection. 所有这些都可以通过反射的“简单”应用程序找到。
On top of these you can take a look at local variables of methods/properties (they are methods in the end), events (even they are methods in the end): if you have a MethodInfo method
, you can get a MethodBody body = method.GetMethodBody()
, and the MethodBody
defines a LocalVariables
. 最重要的是,您可以查看方法/属性的局部变量(最后是方法),事件(甚至最后是方法):如果有
MethodInfo method
,则可以获得MethodBody body = method.GetMethodBody()
和MethodBody
定义了LocalVariables
。
Note that without disassembling the code (for example with Mono.Cecil ) you won't be able to detect that in 请注意,如果不反汇编代码(例如,使用Mono.Cecil ),您将无法在
public class C
{
public List<int> MyList;
public void M()
{
MyList = new List<int>();
Console.WriteLine(new List<int>());
}
}
the method M
uses a List<int>()
, because no local variable of type List<int>
is used. 该方法
M
使用List<int>()
因为型的没有局部变量List<int>
时使用。 So in the end you'll need to even disassemble all the methods. 因此,最后您甚至需要反汇编所有方法。
Clearly each time you find a type, you must check if the type is a Foo<>
, a subclass of Foo<>
, or perhaps uses Foo<>
as a parameter ( List<Foo<>>
), or is a pointer Foo<>*
, or a managed pointer ref Foo<>
or...) 显然,每找到一个类型的时候,你必须检查类型是
Foo<>
的一个子类Foo<>
或者使用Foo<>
作为参数( List<Foo<>>
),或者是一个指针Foo<>*
或托管指针ref Foo<>
或...)
As far as variables is concerned, you could discover the types by examining the method. 就变量而言,您可以通过检查方法来发现类型。
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);
}
}
}
Output: 输出:
System.Int32
System.Int32
System.String
System.String
You would have to recurse over the assemblies and types though. 但是,您将必须递归处理程序集和类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.