Chiamare una funzione da una stringa in C #


145

So che in php sei in grado di effettuare una chiamata come:

$function_name = 'hello';
$function_name();

function hello() { echo 'hello'; }

Questo è possibile in .Net?


2
Ho visto che anche il tuo metodo dovrebbe essere public.
zapoo,

Risposte:


268

Sì. Puoi usare la riflessione. Qualcosa come questo:

Type thisType = this.GetType();
MethodInfo theMethod = thisType.GetMethod(TheCommandString);
theMethod.Invoke(this, userParameters);

56
E questo richiede "usando System.Reflection;"
jptsetung,

1
Potrebbe essere usato anche per invocare una funzione con parametro: es. Stringa f = "metodo (parametro1, parametro2)";
Tuono

Grazie @ottobar per la risposta. Non so se questo è anche quello che sto cercando: avevo bisogno di usare una funzione scalare SQL nel mio codice c #. Come lo chiamo?
Chagbert,

1
Cordiali saluti, questo non funziona se hai metodi sovraccarichi.
Sean O'Neil,

Con il codice sopra - Il metodo che viene invocato deve avere un modificatore di accesso - PUBLIC. Se non pubblico, utilizzare i flag Binding - BindingFlags.NonPublic | BindingFlags.Instance .. Type thisType = this.GetType(); MethodInfo theMethod = thisType.GetMethod(TheCommandString, BindingFlags.NonPublic | BindingFlags.Instance); theMethod.Invoke(this, userParameters);
Sibgath,

75

Puoi invocare metodi di un'istanza di classe usando reflection, facendo una chiamata dinamica al metodo:

Supponiamo di avere un metodo chiamato ciao in un'istanza effettiva (questa):

string methodName = "hello";

//Get the method information using the method info class
 MethodInfo mi = this.GetType().GetMethod(methodName);

//Invoke the method
// (null- no parameter for the method call
// or you can pass the array of parameters...)
mi.Invoke(this, null);

1
che dire dei metodi di una classe "stringa"? utilizzando il framework 4
Leandro,

36
class Program
    {
        static void Main(string[] args)
        {
            Type type = typeof(MyReflectionClass);
            MethodInfo method = type.GetMethod("MyMethod");
            MyReflectionClass c = new MyReflectionClass();
            string result = (string)method.Invoke(c, null);
            Console.WriteLine(result);

        }
    }

    public class MyReflectionClass
    {
        public string MyMethod()
        {
            return DateTime.Now.ToString();
        }
    }

questo non dipende dalla classe
Leandro,

E metodo nullo?
Kiquenet,

2

Una leggera tangente: se si desidera analizzare e valutare un'intera stringa di espressioni che contiene funzioni (nidificate!), Considerare NCalc ( http://ncalc.codeplex.com/ e nuget)

Ex. leggermente modificato dalla documentazione del progetto:

// the expression to evaluate, e.g. from user input (like a calculator program, hint hint college students)
var exprStr = "10 + MyFunction(3, 6)";
Expression e = new Expression(exprString);

// tell it how to handle your custom function
e.EvaluateFunction += delegate(string name, FunctionArgs args) {
        if (name == "MyFunction")
            args.Result = (int)args.Parameters[0].Evaluate() + (int)args.Parameters[1].Evaluate();
    };

// confirm it worked
Debug.Assert(19 == e.Evaluate());

E all'interno del EvaluateFunctiondelegato chiamereste la vostra funzione esistente.


0

In effetti, sto lavorando su Windows Workflow 4.5 e sono riuscito a trovare un modo per passare un delegato da una macchina a un metodo senza successo. L'unico modo che ho trovato è stato passare una stringa con il nome del metodo che volevo passare come delegato e convertire la stringa in un delegato all'interno del metodo. Risposta molto bella. Grazie. Controlla questo link https://msdn.microsoft.com/en-us/library/53cz7sc6(v=vs.110).aspx


0
Questo codice funziona nella mia applicazione console .Net
class Program
{
    static void Main(string[] args)
    {
        string method = args[0]; // get name method
        CallMethod(method);
    }
    
    public static void CallMethod(string method)
    {
        try
        {
            Type type = typeof(Program);
            MethodInfo methodInfo = type.GetMethod(method);
            methodInfo.Invoke(method, null);
        }
        catch(Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            Console.ReadKey();
        }
    }
    
    public static void Hello()
    {
        string a = "hello world!";
        Console.WriteLine(a);
        Console.ReadKey();
    }
}

Benvenuti in SO! Mi piace la tua risposta, potresti semplicemente spiegare qualcosa in più su quello che stai facendo?
a.deshpande012,

Ciao, certo. Questa è un'applicazione console .net, all'interno della "classe di programma" ci sono diversi metodi o funzioni, ad esempio: ciao, ciao2, ciao2. Il metodo "CallMethod (metodo stringa)" cerca e consente di invocare qualsiasi metodo all'interno della "classe di programma" invocato dal suo nome come parametro stringa. Quando eseguo l'applicazione da "Console di Windows": scrivo: "app nome" + "metodo ho bisogno di invocare". Ad esempio: myapp ciao, quindi restituisci "ciao mondo!". Potrebbe anche essere "myapp hello2" o "myapp hello3". Penso che potrebbe funzionare in qualsiasi applicazione .Net.
ranobe,

Devi aggiungere la classe Reflection: "using System.Reflection;".
ranobe,

-9

In C #, è possibile creare delegati come puntatori a funzioni. Consulta il seguente articolo MSDN per informazioni sull'utilizzo:http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx

    public static void hello()
    {
        Console.Write("hello world");
    }

   /* code snipped */

    public delegate void functionPointer();

    functionPointer foo = hello;
    foo();  // Writes hello world to the console.

15
questo non proviene da stringhe!
nawfal,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.