c# reflection invokemember

Reflejo de C#: cargue el ensamblaje e invoque un método si existe



reflection invokemember (4)

utilice la reflexión para verificar si tiene un método llamado "CustomType MyMethod (byte [] a, int b)" y llámelo o envíe una excepción de lo contrario

Su código actual no está cumpliendo ese requisito. Pero puedes hacerlo bastante fácilmente con algo como esto:

var methodInfo = t.GetMethod("MyMethod", new Type[] { typeof(byte[]), typeof(int) }); if (methodInfo == null) // the method doesn''t exist { // throw some exception } var o = Activator.CreateInstance(t); var result = methodInfo.Invoke(o, params);

¿Es esto lo suficientemente bueno, o hay formas mejores / más rápidas / más cortas?

En lo que a mí respecta, esta es la mejor manera y realmente no hay nada más rápido por decir.

¿Y los constructores, dado que estos métodos no son estáticos? ¿Pueden simplemente ignorarse?

Aún tendrá que crear una instancia de t como se muestra en mi ejemplo. Esto usará el constructor predeterminado sin argumentos. Si necesita pasar argumentos, puede, simplemente vea la documentación de MSDN y modifíquela como tal.

Quiero cargar un ensamblaje (su nombre está almacenado en una cadena), usar la reflexión para verificar si tiene un método llamado "CustomType MyMethod (byte [] a, int b)" y llamarlo o lanzar una excepción de lo contrario. Creo que debería hacer algo como esto, pero agradecería que alguien pudiera ofrecer el mismo consejo sobre la mejor manera de hacerlo:

Assembly asm = Assembly.Load("myAssembly"); /* 1. does it matter if write myAssembly or myAssembly.dll? */ Type t = asm.GetType("myAssembly.ClassName"); // specify parameters byte[] a = GetParamA(); int b = GetParamB(); object[] params = new object[2]; params[0] = a; params[1] = b; /* 2. invoke method MyMethod() which returns object "CustomType" - how do I check if it exists? */ /* 3. what''s the meaning of 4th parameter (t in this case); MSDN says this is "the Object on which to invoke the specified member", but isn''t this already accounted for by using t.InvokeMember()? */ CustomType result = t.InvokeMember("MyMethod", BindingFlags.InvokeMethod, null, t, params);

¿Es esto lo suficientemente bueno, o hay formas mejores / más rápidas / más cortas? ¿Y los constructores, dado que estos métodos no son estáticos? ¿Pueden simplemente ignorarse?

Al invocar métodos vacíos (), ¿está bien simplemente escribir t.InvokeMember (...) o siempre debe hacer Object obj = t.InvokeMember (...)?

Gracias por adelantado.

EDITAR He proporcionado un ejemplo de trabajo como una respuesta separada a continuación.


Dado que esta parece ser una pregunta popular, aquí está el ejemplo completo del código fuente sobre cómo hacerlo.

Supongamos que tenemos un ensamblado de muestra, MyAssembly.dll , con una clase MyClass . Queremos cargarlo dinámicamente e invocar sus métodos. Código MyAssembly :

namespace MyAssembly { public class MyClass { public int X { get; set; } public int Y { get; set; } public MyClass(int initialX, int initialY) { X = initialX; Y = initialY; } public int MyMethod(int count, string text) { Console.WriteLine("This is a normal method."); Console.WriteLine("Count: {0}", count); Console.WriteLine("Text: {0}", text); return this.X + this.Y; } public static void StaticMethod(int count, float radius) { Console.WriteLine("This is a static method call."); Console.WriteLine("Count: {0}", count); Console.WriteLine("Radius: {0}", radius); } } }

Primero, nos gustaría crear una instancia de la clase usando el constructor MyClass(int initialX, int initialY) , luego llamamos al método public int MyMethod(int count, string text) . Así es como lo hace desde otro proyecto (por ejemplo, una aplicación de consola):

static void Main(string[] args) { // // 1. Load assembly "MyAssembly.dll" from file path. Specify that we will be using class MyAssembly.MyClass // Assembly asm = Assembly.LoadFrom(@"C:/Path/MyAssembly.dll"); Type t = asm.GetType("MyAssembly.MyClass"); // // 2. We will be invoking a method: ''public int MyMethod(int count, string text)'' // var methodInfo = t.GetMethod("MyMethod", new Type[] { typeof(int), typeof(string) }); if (methodInfo == null) { // never throw generic Exception - replace this with some other exception type throw new Exception("No such method exists."); } // // 3. Define parameters for class constructor ''MyClass(int initialX, int initialY)'' // object[] constructorParameters = new object[2]; constructorParameters[0] = 999; // First parameter. constructorParameters[1] = 2; // Second parameter. // // 4. Create instance of MyClass. // var o = Activator.CreateInstance(t, constructorParameters); // // 5. Specify parameters for the method we will be invoking: ''int MyMethod(int count, string text)'' // object[] parameters = new object[2]; parameters[0] = 124; // ''count'' parameter parameters[1] = "Some text."; // ''text'' parameter // // 6. Invoke method ''int MyMethod(int count, string text)'' // var r = methodInfo.Invoke(o, parameters); Console.WriteLine(r); }

Llamando al método estático public static void StaticMethod(int count, float radius) ve así:

var methodInfoStatic = t.GetMethod("StaticMethod"); if (methodInfoStatic == null) { // never throw generic Exception - replace this with some other exception type throw new Exception("No such static method exists."); } // Specify parameters for static method: ''public static void MyMethod(int count, float radius)'' object[] staticParameters = new object[2]; staticParameters[0] = 10; staticParameters[1] = 3.14159f; // Invoke static method methodInfoStatic.Invoke(o, staticParameters);


Puede usar el tipo dinámico, que se resolverá en tiempo de ejecución.

Type type = Type.GetType(className, true); dynamic instance = Activator.CreateInstance(type); var response = instance.YourMethod();


Assembly assembly = Assembly.LoadFile("myAssembly"); Type type = assembly.GetType("myAssembly.ClassName"); if (type != null) { MethodInfo methodInfo = type.GetMethod("MyMethod"); 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); } } }