简体   繁体   English

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

[英]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.

相关问题 为什么在 .NET 5 中用作通用类型 arguments 时引用类型“较慢”? - Why are reference types "slower" when used as generic type arguments in .NET 5? 使用带有Autofac的Type变量获取实现通用接口的所有类型 - Get all types implementing generic interface using Type variable with Autofac 获取实现特定开放泛型类型的所有类型 - Get all types implementing specific open generic type 为什么无法推断泛型类型的类型参数? - Why type arguments cannot be inferred for generic types? 当用作泛型类型参数时,为什么“动态”不是所有类型的协变和逆变? - Why is “dynamic” not covariant and contravariant with respect to all types when used as a generic type parameter? 如何获取在数组的方法中使用的泛型类型? - How to get the generic types used in a method in an array? 如何从泛型定义和泛型参数中获取泛型类型? - How to get generic type from generic definition and generic arguments? autofac解析所有类型的开放泛型类型? - autofac Resolve all types of open generic type? 非通用类型&#39;IdentityUser&#39;不能与类型参数一起使用 - The non-generic type 'IdentityUser' cannot be used with type arguments 意外的“非泛型类型不能与类型参数一起使用”? - An unexpected “The non-generic type cannot be used with the type arguments”?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM