获取用作通用类型参数的所有类型

时间:2018-07-12 13:28:02

标签: c# .net

是否可以获取在某些程序集中用作通用类型参数的所有类型?

基本上,假设我有这个课程:

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>)构造的所有类型。

那有可能吗?

2 个答案:

答案 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

尽管如此,您必须递归遍历程序集和类型。