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