反思:如何用参数调用方法
我想通过参数reflection调用一个方法,我得到:
对象与目标types不匹配
如果我调用没有参数的方法,它工作正常。 如果我调用Test("TestNoParameters")
方法,基于下面的代码,它工作正常。 但是,如果我打电话Test("Run")
,我得到一个例外。 我的代码有问题吗?
我最初的目的是传递一个对象数组,如public void Run(object[] options)
但这不起作用,我尝试了一些简单的,如string没有成功。
// 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); } } } } }
将“methodInfo”更改为“classInstance”,就像在用null参数数组调用一样。
result = methodInfo.Invoke(classInstance, parametersArray);
你有一个错误在那里
result = methodInfo.Invoke(methodInfo, parametersArray);
它应该是
result = methodInfo.Invoke(classInstance, parametersArray);
一个根本的错误在这里:
result = methodInfo.Invoke(methodInfo, parametersArray);
您正在调用MethodInfo
实例的方法。 您需要传入要调用的对象types的实例。
result = methodInfo.Invoke(classInstance, parametersArray);
提供的解决scheme不适用于从远程程序集加载的types的实例。 要做到这一点,下面是一个适用于所有情况的解决scheme,它涉及通过CreateInstance调用返回的types的显式types重新映射。
这是我需要创build我的classInstance,因为它位于远程程序集中。
// sample of my CreateInstance call with an explicit assembly reference object classInstance = Activator.CreateInstance(assemblyName, type.FullName);
然而,即使有上面提供的答案,你仍然会得到同样的错误。 这里是如何去做:
// 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();
然后像在这里提到的其他用户一样。
我会像这样使用它,它的方式更短,也不会有任何问题
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); }