views:

1673

answers:

3

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.

+3  A: 

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
Interestingly enough, this didn't work. I passed no parameters to my parameterless method, and I still got an ambiguous call.
Wes P
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
Not a problem - the underlying types of the parameters are what is checked.
Keith
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
See this question for an example of that: http://stackoverflow.com/questions/154112
Keith
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
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
A: 

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
+8  A: 

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]);
Hallgrim