Coder Perfect

How to Invoke a Method with Parameters (Reflection)

Problem

I’m trying to use reflection to call a function with parameters, but I’m getting the following error:

It works perfectly if I call a method without parameters. If I call the method Test(“TestNoParameters”) with the following code, it works perfectly. When I call Test(“Run”), however, I receive an exception. Is there a problem with my code?

My initial goal was to pass an array of objects, such as public void Run(object[] options), but this did not work, so I tried something simpler, such as string, but that did not work either.

// Assembly1.dll
namespace TestAssembly
{
    public class Main
    {
        public void Run(string parameters)
        { 
            // Do something... 
        }
        public void TestNoParameters()
        {
            // Do something... 
        }
    }
}

// Executing Assembly.exe
public class TestReflection
{
    public void Test(string methodName)
    {
        Assembly assembly = Assembly.LoadFile("...Assembly1.dll");
        Type type = assembly.GetType("TestAssembly.Main");

        if (type != null)
        {
            MethodInfo methodInfo = type.GetMethod(methodName);

            if (methodInfo != null)
            {
                object result = null;
                ParameterInfo[] parameters = methodInfo.GetParameters();
                object classInstance = Activator.CreateInstance(type, null);

                if (parameters.Length == 0)
                {
                    // This works fine
                    result = methodInfo.Invoke(classInstance, null);
                }
                else
                {
                    object[] parametersArray = new object[] { "Hello" };

                    // The invoke does NOT work;
                    // it throws "Object does not match target type"             
                    result = methodInfo.Invoke(methodInfo, parametersArray);
                }
            }
        }
    }
}

Asked by Ioannis

Solution #1

Just like in the call with the null parameter array, change “methodInfo” to “classInstance.”

  result = methodInfo.Invoke(classInstance, parametersArray);

Answered by womp

Solution #2

You’ve got a bug on your hands.

result = methodInfo.Invoke(methodInfo, parametersArray);

it should be

result = methodInfo.Invoke(classInstance, parametersArray);

Answered by Oleg I.

Solution #3

There’s a major blunder here:

result = methodInfo.Invoke(methodInfo, parametersArray); 

You’re calling the method on a MethodInfo object. You must provide an instance of the object type that you want to invoke.

result = methodInfo.Invoke(classInstance, parametersArray);

Answered by jason

Solution #4

For instances of types loaded from a remote assembly, the offered solution does not function. To do so, here’s a solution that works in every situation: an explicit type re-mapping of the type returned by the CreateInstance method.

Because my classInstance was in a remote assembly, I needed to do it this way.

// sample of my CreateInstance call with an explicit assembly reference
object classInstance = Activator.CreateInstance(assemblyName, type.FullName); 

However, even with the answer provided above, you’d still get the same error. Here’s how to get started:

// first, create a handle instead of the actual object
ObjectHandle classInstanceHandle = Activator.CreateInstance(assemblyName, type.FullName);
// unwrap the real slim-shady
object classInstance = classInstanceHandle.Unwrap(); 
// re-map the type to that of the object we retrieved
type = classInstace.GetType(); 

Then do as the other people have suggested.

Answered by Martin Kool

Solution #5

I’d use it like this because it’s much shorter and won’t cause any issues.

        dynamic result = null;
        if (methodInfo != null)
        {
            ParameterInfo[] parameters = methodInfo.GetParameters();
            object classInstance = Activator.CreateInstance(type, null);
            result = methodInfo.Invoke(classInstance, parameters.Length == 0 ? null : parametersArray);
        }

Answered by Nick N.

Post is based on https://stackoverflow.com/questions/2202381/reflection-how-to-invoke-method-with-parameters