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.

3 Answers 3

136

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]);
Sign up to request clarification or add additional context in comments.

5 Comments

You can also do Type.EmptyTypes
need } after "typeof(int), typeof(string)" to compile :)
What if one of the args is generic?
When you have an object instance you know what types it has been instantiated with.
And if you need to specify an out parameter, do not mess with modifiers, that does not work (for me). You need to pass the type object with its IsByRef property set to true. IsByRef is readonly though, you need to use the MakeByRefType method of type to convert the type to an instance that has this property set.
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.

7 Comments

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

1 Comment

You can use Type.EmptyTypes

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.