如何使用反射来调用.NET中的重载方法


75

有没有一种方法可以使用.NET(2.0)中的反射来调用重载方法。我有一个应用程序,该应用程序可以动态实例化从通用基类派生的类。出于兼容性目的,此基类包含2个同名的方法,一个带有参数,另一个不带参数。我需要通过Invoke方法调用无参数方法。现在,我得到的只是一个错误,告诉我我正在尝试调用一个模棱两可的方法。

是的,我可以将对象强制转换为基类的实例,然后调用所需的方法。最终发生这种情况,但是现在,内部复杂性是不允许的。

任何帮助将是巨大的!谢谢。

Answers:


120

您必须指定所需的方法:

class SomeType 
{
    void Foo(int size, string bar) { }
    void Foo() { }
}

SomeType obj = new SomeType();
// call with int and string arguments
obj.GetType()
    .GetMethod("Foo", new Type[] { typeof(int), typeof(string) })
    .Invoke(obj, new object[] { 42, "Hello" });
// call without arguments
obj.GetType()
    .GetMethod("Foo", new Type[0])
    .Invoke(obj, new object[0]);

7
您也可以做Type.EmptyTypes
yoel halb

2
需要在“ typeof(int),typeof(string)”之后进行编译:)
Omid-RH,2015年

1
如果其中一个参数是通用的怎么办?
史蒂文·特纳

当您有一个对象实例时,您就知道实例化了什么类型。
Hallgrim

而且,如果您需要指定out参数,请不要与修饰符混淆,这对我不起作用。您需要传递其IsByRef属性设置为true的类型对象。IsByRef是只读的,但是您需要使用类型的MakeByRefType方法将类型转换为具有此属性集的实例。
马丁·马特

17

是。调用该方法时,传递与所需重载匹配的参数。

例如:

Type tp = myInstance.GetType();

//call parameter-free overload
tp.InvokeMember( "methodName", BindingFlags.InvokeMethod, 
   Type.DefaultBinder, myInstance, new object[0] );

//call parameter-ed overload
tp.InvokeMember( "methodName", BindingFlags.InvokeMethod, 
   Type.DefaultBinder, myInstance, new { param1, param2 } );

如果以相反的方式执行此操作(即,通过找到MemberInfo并调用Invoke),请小心,以确保正确无误-可能是首次发现无参数重载。


有趣的是,这没有用。我没有向无参数方法传递任何参数,但仍然有一个模棱两可的调用。
Wes P

如何处理不同类型的参数?假设我有两个重载,其中一个重载字符串,另一个重载int?
smaclell

没问题-检查参数的基本类型。
基思

要注意的是,当您具有隐式转换为彼此的类型时-.Net会选择实例方法而不是继承的方法。
基思

参见以下问题的示例:stackoverflow.com/questions/154112
Keith,

5

使用采用System.Type []的GetMethod重载,并传递一个空的Type [];

typeof ( Class ).GetMethod ( "Method", new Type [ 0 ] { } ).Invoke ( instance, null );

3
您可以使用Type.EmptyTypes
yoel halb
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.