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?


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

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

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

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.


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


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

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.

15
ce n'est pas des cordes!
nawfal
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.