with unity method c# reflection parameters methods invoke

c# - unity - Reflexión: Cómo invocar el método con parámetros



reflection c# (7)

Cambie "methodInfo" por "classInstance", como en la llamada con la matriz de parámetros null.

result = methodInfo.Invoke(classInstance, parametersArray);

Intento invocar un método a través de la reflexión con parámetros y obtengo:

objeto no coincide con el tipo de objetivo

Si invoco un método sin parámetros, funciona bien. Basado en el siguiente código si llamo al método Test("TestNoParameters") , funciona bien. Sin embargo, si llamo a Test("Run") , recibo una excepción. ¿Hay algún problema con mi código?

Mi propósito inicial era pasar una serie de objetos, por ejemplo, public void Run(object[] options) pero esto no funcionó y traté de algo más simple, por ejemplo, una cadena sin éxito.

// 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); } } } } }


La solución proporcionada no funciona para instancias de tipos cargados desde un ensamblaje remoto. Para hacerlo, aquí hay una solución que funciona en todas las situaciones, lo que implica una nueva asignación explícita de tipo del tipo devuelto a través de la llamada CreateInstance.

Así es como tengo que crear mi claseInstance, ya que se encuentra en un conjunto remoto.

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

Sin embargo, incluso con la respuesta proporcionada anteriormente, igual obtendría el mismo error. Aquí es cómo hacerlo:

// 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();

Luego haz lo que otros usuarios mencionaron aquí.


Lo usaría así, es mucho más corto y no dará ningún problema

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); }


Tienes un error ahí

result = methodInfo.Invoke(methodInfo, parametersArray);

debería ser

result = methodInfo.Invoke(classInstance, parametersArray);


Traté de trabajar con todas las respuestas sugeridas arriba, pero nada parece funcionar para mí. Así que estoy tratando de explicar qué funcionó para mí aquí.

Creo que si está llamando a algún método como el Main continuación o incluso con un único parámetro como en su pregunta, solo tiene que cambiar el tipo de parámetro de string a object para que esto funcione

class Class1 { public static void Execute(object[] str) {...} }

Luego, debe pasar el parámetro Array dentro de una matriz de objetos como la siguiente al invocarlo.

MethodInfo mi = typeInstance.GetType().GetMethod("Execute"); ParameterInfo[] parameters = mi.GetParameters(); object classInstance = Activator.CreateInstance(typeInstance.GetType(), null); if (parameters.Length == 0) { // This works fine var result = mi.Invoke(classInstance, null); } else { object[] parametersArray = new object[] { "Hello","bye" }; var result = mi.Invoke(classInstance,new object[] { parametersArray } ); }

Espero que esto ayude


Un error fundamental está aquí:

result = methodInfo.Invoke(methodInfo, parametersArray);

Está invocando el método en una instancia de MethodInfo . Debe pasar una instancia del tipo de objeto sobre el que desea invocar.

result = methodInfo.Invoke(classInstance, parametersArray);


Assembly assembly = Assembly.LoadFile(@"....bin/Debug/TestCases.dll"); //get all types var testTypes = from t in assembly.GetTypes() let attributes = t.GetCustomAttributes(typeof(NUnit.Framework.TestFixtureAttribute), true) where attributes != null && attributes.Length > 0 orderby t.Name select t; foreach (var type in testTypes) { //get test method in types. var testMethods = from m in type.GetMethods() let attributes = m.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute), true) where attributes != null && attributes.Length > 0 orderby m.Name select m; foreach (var method in testMethods) { MethodInfo methodInfo = type.GetMethod(method.Name); 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(classInstance, parametersArray); } } } }