Appel d'une fonction à partir d'une chaîne en C #

145

Je sais qu'en php, vous pouvez passer un appel comme:

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

function hello() { echo 'hello'; }

Est-ce possible dans .Net?

Jeremy Boyd
la source
2
J'ai vu que votre méthode devrait l'être publicégalement.
zapoo le

Réponses:

268

Oui. Vous pouvez utiliser la réflexion. Quelque chose comme ça:

Type thisType = this.GetType();
MethodInfo theMethod = thisType.GetMethod(TheCommandString);
theMethod.Invoke(this, userParameters);
ottobar
la source
56
Et cela nécessite "d'utiliser System.Reflection;"
jptsetung
1
Cela pourrait-il également être utilisé pour appeler une fonction avec un paramètre: par exemple, chaîne f = "méthode (paramètre1, paramètre2)";
Thunder
Merci @ottobar pour la réponse. Je ne sais pas si c'est ce que je recherche également: j'avais besoin d'utiliser une fonction scalaire SQL dans mon code c #. Comment l'appeler?
Chagbert
1
Pour info, cela ne fonctionne pas si vous avez des méthodes surchargées.
Sean O'Neil
Avec le code ci-dessus - La méthode qui est appelée doit avoir un modificateur d'accès - PUBLIC. Si non public, veuillez utiliser les indicateurs de liaison - BindingFlags.NonPublic | BindingFlags.Instance .. Type thisType = this.GetType(); MethodInfo theMethod = thisType.GetMethod(TheCommandString, BindingFlags.NonPublic | BindingFlags.Instance); theMethod.Invoke(this, userParameters);
Sibgath
75

Vous pouvez appeler des méthodes d'une instance de classe à l'aide de la réflexion, en effectuant un appel de méthode dynamique:

Supposons que vous ayez une méthode appelée hello dans une instance réelle (this):

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);
CMS
la source
1
qu'en est-il des méthodes d'une classe "string"? using 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();
        }
    }
BGratuit
la source
ce n'est pas dépendant de classe
Leandro
Et la méthode nulle?
Kiquenet
2

Une légère tangente - si vous voulez analyser et évaluer une chaîne d'expression entière qui contient des fonctions (imbriquées!), Considérez NCalc ( http://ncalc.codeplex.com/ et nuget)

Ex. légèrement modifié par rapport à la documentation du projet:

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

Et au sein du EvaluateFunctiondélégué, vous appelleriez votre fonction existante.

drzaus
la source
0

En fait, je travaille sur Windows Workflow 4.5 et j'ai trouvé un moyen de passer un délégué d'un statemachine à une méthode sans succès. Le seul moyen que j'ai pu trouver était de passer une chaîne avec le nom de la méthode que je voulais passer en tant que délégué et de convertir la chaîne en délégué à l'intérieur de la méthode. Très belle réponse. Merci. Vérifiez ce lien https://msdn.microsoft.com/en-us/library/53cz7sc6(v=vs.110).aspx

Antonio Leite
la source
0
Ce code fonctionne dans mon application 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();
    }
}
Ranobe
la source
Bienvenue à SO! J'aime votre réponse, pouvez-vous expliquer un peu plus ce que vous faites?
a.deshpande012 le
Salut, bien sûr. Il s'agit d'une application console .net, dans la "classe de programme", il y a plusieurs méthodes ou fonctions, par exemple: bonjour, bonjour2, bonjour2. La méthode "CallMethod (méthode de chaîne)" recherche et me laisse invoquer n'importe quelle méthode à l'intérieur de la "classe de programme" appelée par son nom comme paramètre de chaîne. Lorsque j'exécute l'application depuis "Windows Console": j'écris: "name app" + "method I need invoke". Par exemple: myapp hello, puis renvoie "hello world!". Peut être aussi "myapp hello2" ou "myapp hello3". Je pense que cela pourrait fonctionner dans n'importe quelle application .Net.
ranobe le
Vous devez ajouter la classe Reflection: "using System.Reflection;".
ranobe
-9

En C #, vous pouvez créer des délégués en tant que pointeurs de fonction. Consultez l'article MSDN suivant pour plus d'informations sur l'utilisation: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.
regex
la source
15
ce n'est pas des cordes!
nawfal