GetMethod 的 Type[] 以获取具有两个参数和一个类型参数的泛型方法

Posted

技术标签:

【中文标题】GetMethod 的 Type[] 以获取具有两个参数和一个类型参数的泛型方法【英文标题】:Type[] for GetMethod to get generic method with two arguments and one type parameter 【发布时间】:2021-12-18 22:54:39 【问题描述】:

存在许多如何接收泛型方法的变体:通过 LINQ 等在所有方法列表中搜索 (Type.GetMethods()) 或通过创建委托作为方法模板。 但有趣的是为什么它不能使用反射的经典 GetMethod()。 在这种情况下,我们的主要问题是使用所需的方法参数列表(方法签名)创建正确的 Type[]。 我能理解这是c#的限制还是在这个例子中有其他解释? 最初我们有一个类

public class MyClass 

    public static void AddLink()
    
        Console.WriteLine("Hello from AddLink()");
    
    public static void AddLink<T0>(UnityAction<T0> unityAction, UnityEvent<T0> unityEvent)
    
        unityEvent.AddListener(unityAction);
    
    public static void AddLink<T0, T1>(UnityAction<T0, T1> unityAction, UnityEvent<T0, T1> unityEvent)
    
        unityEvent.AddListener(unityAction);
    

我们想通过使用MethodInfo method = typeof(MyClass).GetMethod("AddLink", typeParameters) 来获得方法void AddLink&lt;T0&gt;(UnityAction&lt;T0&gt; unityAction, UnityEvent&lt;T0&gt; unityEvent)。我测试了typeParameters的不同变体

Type[] typeParameters = new Type[] typeof(UnityAction<>), typeof(UnityEvent<>);
Type[] typeParametersClosed = new Type[]  typeof(UnityAction<bool>), typeof(UnityEvent<bool>) ;
Type[] typeParametersClosedGeneric = new Type[]  typeof(UnityAction<bool>).GetGenericTypeDefinition(), typeof(UnityEvent<bool>).GetGenericTypeDefinition();

没有人给出结果。我可以通过在 GetMthods() 中搜索或将委托强制转换为要求类型来找到该方法:

var template = (Action<UnityAction<object>, UnityEvent<object>>)(MyClass.AddLink);
MethodInfo methodGeneric = template.Method.GetGenericMethodDefinition();

为了测试,我决定从建立的方法中获取参数

Type[] typeParametersFromGeneric = GetParametersFromMethodInfo(methodGeneric);

public static Type[] GetParametersFromMethodInfo(MethodInfo method)

    ParameterInfo[] parameterInfo = method.GetParameters();
    int length = parameterInfo.Length;
    Type[] parameters = new Type[length];
    for (int i = 0; i < length; i++)
    
        parameters[i] = parameterInfo[i].ParameterType;
    
    return parameters;

:) 之后,使用 GetMethod 开始工作的最终 Type[] (typeParametersFromGeneric)。

我比较了所有这些 Type[] (我在这里从第二个参数中删除了信息,它是相同的):

主要问题是否可以从头开始创建 Type[] (typeParametersFromGeneric)?以及为什么不可能

【问题讨论】:

【参考方案1】:

您可以使用Type.MakeGenericSignatureType 并将Type.MakeGenericMethodParameter(0) 作为通用参数传递给它:

var methodInfo = typeof(MyClass)
    .GetMethod(nameof(MyClass.AddLink), new[]
    
        Type.MakeGenericSignatureType(typeof(UnityAction<>), Type.MakeGenericMethodParameter(0)),
        Type.MakeGenericSignatureType(typeof(UnityEvent<>), Type.MakeGenericMethodParameter(0))
    );

Demo

【讨论】:

是的,你绝对正确。它有效,它关闭了我的格式塔 :) 但它只能在 Net 3.0 及更高版本中工作(在 .NET Framework 中不支持),但对我来说这是一个概念问题。 PS> 构造的元素有一个带有所需标志的类型:IsConstructedGenericType = true, IsGenericTypeDefinition = false, ContainsGenericParameters = true,但元素的内部类型是其他的 - System.Type System.Reflection.SignatureConstructedGenericType 与原始System.Type System.RuntimeType跨度>

以上是关于GetMethod 的 Type[] 以获取具有两个参数和一个类型参数的泛型方法的主要内容,如果未能解决你的问题,请参考以下文章

java 反射使用 Class.getMethod 应注意

在 GetMethod 中处理泛型类型

Symfony getMethod() 与 getRealMethod()

在这个简单的Clojure Ring应用程序中获取默认index.html文件以具有正确的Content-Type的正确方法是什么?

C#控制台 assembly与getmethod获取一个dll中的类的公有函数名

bean 中私有字段的 getDeclaredField(String) 与 getMethod(String)