如何使用 InvokeMember 通过反射调用泛型方法

时间:2020-12-20 14:27:24

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

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

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() 之类的方法

2 个答案:

答案 0 :(得分:0)

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

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

最终代码:

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");
        }
    }

答案 1 :(得分:0)

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

<块引用>

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

相关问题