简体   繁体   中英

How to call generic method by reflection using InvokeMember

I need to call a method via reflection. But the thing is that I don't want to find a method, I want to evaluate it at run-time using arguments. This is what I try to do:

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

The first call works fine but the second one generates an exception saying that Write() was not found. Can I call it using InvokeMember anyhow? I don't want trying to look for all methods and then call something like MakeGenericMethod()

Your second invoke try to call Write method with two int input but doesn't find any method with this signature in Test class.

You can move T2 to class definition like this: public class Test<T, T2> and set T2 in type declaration like this: var type = typeof(Test<int,int>)

Final Code:

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

Seems to be it is not possible. Remarks section in the documentation here explicitly says that

You cannot use InvokeMember to invoke a generic method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM