【问题标题】:How to call generic method by reflection using InvokeMember如何使用 InvokeMember 通过反射调用泛型方法
【发布时间】:2020-12-20 14:27:24
【问题描述】:

我需要通过反射调用方法。但问题是我不想找到一种方法,我想在运行时使用参数对其进行评估。这是我尝试做的:

class Program
{
    static void Main(string[] args)
    {
        var type = typeof(Test<int>);
        type.InvokeMember("Write", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
            null, new Test<int>(), new object[] {1, "1"});
        // The next call fails
        type.InvokeMember("Write", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
            null, new Test<int>(), new object[] { 2, 2 });
    }
}

public class Test<T>
{
    public void Write(T arg1, string arg2)
    {
        Console.Write(arg1);
        Console.Write(arg2);
        Console.WriteLine(" write1");
    }

    public void Write<T2>(T arg1, T2 arg2)
    {
        Console.Write(arg1);
        Console.Write(arg2);
        Console.WriteLine(" write2");
    }
}

第一个调用工作正常,但第二个调用生成一个异常,指出未找到 Write()。我可以使用 InvokeMember 调用它吗?我不想尝试查找所有方法,然后调用 MakeGenericMethod() 之类的方法

【问题讨论】:

    标签: c# .net .net-core reflection


    【解决方案1】:

    您的第二次调用尝试使用两个 int 输入调用 Write 方法,但在 Test 类中找不到具有此签名的任何方法。

    您可以像这样将T2 移动到类定义中:public class Test&lt;T, T2&gt; 并在类型声明中设置T2,如下所示:var type = typeof(Test&lt;int,int&gt;)

    最终代码:

    class Program
        {
            static void Main(string[] args)
            {
                var type = typeof(Test<int, long>);
                var instance = Activator.CreateInstance(type);
                type.InvokeMember("Write", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
                    null, instance, new object[] { 1, "1" });
    
                type.InvokeMember("Write", BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod,
                    null, instance, new object[] { 2, 22 });
            }
        }
    
        public class Test<T, T2>
        {
            public void Write(T arg1, string arg2)
            {
                Console.Write(arg1);
                Console.Write(arg2);
                Console.WriteLine(" write1");
            }
    
            public void Write(T arg1, T2 arg2)
            {
                Console.Write(arg1);
                Console.Write(arg2);
                Console.WriteLine(" write2");
            }
        }
    

    【讨论】:

    • 我不控制测试 class= ) 这就是问题说“通用”的原因
    【解决方案2】:

    似乎是不可能的。文档here 中的备注部分明确表示

    您不能使用InvokeMember 来调用泛型方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-27
      相关资源
      最近更新 更多