79

Is there a way to Invoke an overloaded method using reflection in .NET (2.0). I have an application that dynamically instantiates classes that have been derived from a common base class. For compatibility purposes, this base class contains 2 methods of the same name, one with parameters, and one without. I need to call the parameterless method via the Invoke method. Right now, all I get is an error telling me that I'm trying to call an ambiguous method.

Yes, I could just cast the object as an instance of my base class and call the method I need. Eventually that will happen, but right now, internal complications will not allow it.

Any help would be great! Thanks.

Cheeso
  • 189,189
  • 101
  • 473
  • 713
Wes P
  • 9,622
  • 14
  • 41
  • 48

3 Answers3

134

You have to specify which method you want:

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]);
JG in SD
  • 5,427
  • 3
  • 34
  • 46
Hallgrim
  • 15,143
  • 10
  • 46
  • 54
17

Yes. When you invoke the method pass the parameters that match the overload that you want.

For instance:

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

If you do this the other way round(i.e. by finding the MemberInfo and calling Invoke) be careful that you get the right one - the parameter-free overload could be the first found.

Keith
  • 150,284
  • 78
  • 298
  • 434
  • Interestingly enough, this didn't work. I passed no parameters to my parameterless method, and I still got an ambiguous call. – Wes P Oct 21 '08 at 21:08
  • How does this work with parameters of different types? Say I have two overloads where one takes a string and the other takes an int? – smaclell Oct 21 '08 at 21:10
  • Not a problem - the underlying types of the parameters are what is checked. – Keith Oct 21 '08 at 21:11
  • The thing to be careful of is when you have types that implicitly cast to one another - then .Net picks instance methods over inherited methods. – Keith Oct 21 '08 at 21:12
  • See this question for an example of that: http://stackoverflow.com/questions/154112 – Keith Oct 21 '08 at 21:13
  • Having read other responses, what's the preferred way to do do this? Should I rely on InvokeMember to check the underlying types? Or should I make the call through Type.GetMethod, and explicitly type my parameters? I would think the later saves the runtime a bit of work... ? – Wes P Oct 22 '08 at 13:13
  • If you're calling it once just use mine, as it's slightly less complex. If you're doing it many times use @Hallgrim's and cache the MethodInfo of the overload you want. – Keith Oct 22 '08 at 13:16
5

Use the GetMethod overload that takes a System.Type[], and pass an empty Type[];

typeof ( Class ).GetMethod ( "Method", new Type [ 0 ] { } ).Invoke ( instance, null );
baretta
  • 7,385
  • 1
  • 25
  • 25