2010-07-15 19 views
26

devo metodo:come chiamare dinamicamente una funzione in C#

add(int x,int y) 

e ho anche:

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

è possibile chiamare aggiungere (a, b) utilizzando la stringa s? come posso farlo in C#?

+5

'if (s ==" aggiungi ") {aggiungi (a, b); } 'Questo? – dtb

+0

Penso che stia cercando qualcosa di simile alla funzione 'eval()' di javascript, che non penso esista in C#. Ma sto aspettando con impazienza di vedere come Jon Skeet pesa su questo. –

+0

possibile duplicato di [Richiamare dinamicamente qualsiasi funzione passando il nome della funzione come stringa] (http://stackoverflow.com/questions/801070/dynamically-invoking-any-function-by-passing-function-name-as-string) – kennytm

risposta

48

come posso farlo in C#?

Utilizzo della riflessione.

add deve essere un membro di qualche tipo, quindi (taglio di un sacco di dettagli):

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

Ciò presuppone add è statico (altrimenti primo argomento Invoke è l'oggetto) e I don' t bisogno di parametri aggiuntivi per identificare in modo univoco il metodo nella chiamata GetMethod.

+1

+1. Grazie, ho appena usato questo nel mio codice. Nel caso in cui qualcun altro abbia le difficoltà che ho avuto, questo non funziona con le funzioni private. – David

+0

@DavidStratton Funzionerà con i membri 'private': usa uno degli overload di [' GetMethod'] (http://msdn.microsoft.com/en-us/library/05eey4y9.aspx) che accetta ['BindingFlags '] (http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx) argomento con' BindingFlags.NonPublic'. – Richard

+0

Possiamo usare "Func <>" invece di Refection? – Sreekumar

19

Usa riflessione - provare il metodo Type.GetMethod

Qualcosa di simile

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

Si perde tipizzazione forte e in fase di compilazione - invoke non sa come molti parametri del metodo si aspetta, e quali sono i loro tipi sono e qual è il tipo effettivo del valore restituito. Quindi le cose potrebbero fallire in fase di esecuzione se non si riesce nel modo giusto.

È anche più lento.

10

È possibile utilizzare la riflessione.

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

Se le funzioni sono note al momento della compilazione e si desidera solo evitare di scrivere un'istruzione switch.

Setup:

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

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

Chiamato da:

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

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

@ risposta di Richard è grande. Proprio per espandere un po ':

Questo può essere utile in una situazione in cui è stato creato in modo dinamico un oggetto di tipo sconosciuto e bisogno di chiamare il suo metodo:

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

becasue al momento della compilazione do è solo un Object .

Problemi correlati