2010-07-15 51 views
26

tengo método:cómo llamar dinámicamente una función en C#

add(int x,int y) 

y también tengo:

int a=5; 
int b=6; 
string s="add"; 

es posible llamar añadir (a, b) el uso de la cadena s? ¿Cómo puedo hacer esto en C#?

+5

'if (s ==" add ") {add (a, b); } '¿Esto? – dtb

+0

Creo que está buscando algo similar a la función 'eval()' de JavaScript, que no creo que exista en C#. Pero estoy esperando ansiosamente a ver cómo Jon Skeet pesa en este caso. –

+0

posible duplicado de [Invocar dinámicamente cualquier función pasando el nombre de la función como una cadena] (http://stackoverflow.com/questions/801070/dynamically-invoking-any-function-by-passing-function-name-as-string) – kennytm

Respuesta

48

¿cómo puedo hacer esto en C#?

Usando la reflexión.

add tiene que ser miembro de algún tipo, por lo que (corte de una gran cantidad de detalles):

typeof(MyType).GetMethod("add").Invoke(null, new [] {arg1, arg2}) 

Esto supone add es estática (en caso contrario primer argumento a Invoke es el objeto) y yo don' t necesita parámetros adicionales para identificar de manera única el método en la llamada GetMethod.

+1

+1. Gracias, acabo de usar esto en mi propio código. Solo en caso de que alguien más tenga las dificultades que tuve, esto no funciona con funciones privadas. – David

+0

@DavidStratton Funcionará con miembros 'privados': use una de las sobrecargas de [' GetMethod'] (http://msdn.microsoft.com/en-us/library/05eey4y9.aspx) que tome un ['BindingFlags '] (http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx) argumento con' BindingFlags.NonPublic'. – Richard

+0

¿Podemos usar "Func <>" en lugar de Refection? – Sreekumar

19

Uso reflexión - intente el método Type.GetMethod

Algo así como

MethodInfo addMethod = this.GetType().GetMethod("add"); 
object result = addMethod.Invoke(this, new object[] { x, y }); 

Se pierde una gran escritura y el tiempo de compilación de cheques - invocación no sabe cuántos parámetros del método espera, y cuáles son sus tipos son y cuál es el tipo real del valor de retorno. Entonces las cosas podrían fallar en tiempo de ejecución si no lo haces bien.

También es más lento.

10

Puede usar el reflejo.

using System; 
using System.Reflection; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Program p = new Program(); 
      Type t = p.GetType(); 
      MethodInfo mi = t.GetMethod("add", BindingFlags.NonPublic | BindingFlags.Instance); 
      string result = mi.Invoke(p, new object[] {4, 5}).ToString(); 
      Console.WriteLine("Result = " + result); 
      Console.ReadLine(); 
     } 

     private int add(int x, int y) 
     { 
      return x + y; 
     } 
    } 
} 
11

Si las funciones son conocidas en tiempo de compilación y solo quiere evitar escribir una instrucción de cambio.

Configuración:

Dictionary<string, Func<int, int, int>> functions = 
    new Dictionary<string, Func<int, int, int>>(); 

functions["add"] = this.add; 
functions["subtract"] = this.subtract; 

Llamado por:

string functionName = "add"; 
int x = 1; 
int y = 2; 

int z = functions[functionName](x, y); 
0

@ respuesta de Richard es grande. Sólo para ampliar un poco:

Esto puede ser útil en una situación en la que creó dinámicamente un objeto de tipo desconocido y la necesidad de llamar a su método:

var do = xs.Deserialize(new XmlTextReader(ms)); // example - XML deserialization 
do.GetType().GetMethod("myMethodName").Invoke(do, new [] {arg1, arg2}); 

robaba en tiempo de compilación do es sólo un Object .

Cuestiones relacionadas