Aufrufen einer Funktion aus einer Zeichenfolge in C #


145

Ich weiß, dass Sie in PHP einen Anruf tätigen können wie:

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

function hello() { echo 'hello'; }

Ist das in .Net möglich?


2
Ich habe gesehen, dass Ihre Methode auch sein sollte public.
Zapoo

Antworten:


268

Ja. Sie können Reflexion verwenden. Etwas wie das:

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

56
Und dies erfordert "using System.Reflection";
Jptsetung

1
Könnte dies auch verwendet werden, um eine Funktion mit Parameter aufzurufen: zB string f = "method (parameter1, parameter2)";
Donner

Danke @ottobar für die Antwort. Ich weiß nicht, ob dies auch das ist, wonach ich suche: Ich musste eine SQL-Skalarfunktion in meinem C # -Code verwenden. Wie nenne ich es?
Chagbert

1
Zu Ihrer Information, dies funktioniert nicht, wenn Sie Methoden überladen haben.
Sean O'Neil

Mit dem obigen Code muss die aufgerufene Methode den Zugriffsmodifikator PUBLIC haben. Wenn nicht öffentlich, verwenden Sie bitte Bindungsflags - BindingFlags.NonPublic | BindingFlags.Instance .. Type thisType = this.GetType(); MethodInfo theMethod = thisType.GetMethod(TheCommandString, BindingFlags.NonPublic | BindingFlags.Instance); theMethod.Invoke(this, userParameters);
Sibgath

75

Sie können Methoden einer Klasseninstanz mithilfe von Reflection aufrufen und dabei einen dynamischen Methodenaufruf ausführen:

Angenommen, Sie haben eine Methode namens "Hallo" in einer tatsächlichen Instanz (dies):

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
Was ist mit Methoden aus einer "String" -Klasse? mit 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();
        }
    }

Dies ist nicht klassenabhängig
Leandro

Und Methode nichtig?
Kiquenet

2

Eine leichte Tangente - Wenn Sie eine gesamte Ausdruckszeichenfolge analysieren und auswerten möchten, die (verschachtelte!) Funktionen enthält, ziehen Sie NCalc ( http://ncalc.codeplex.com/ und nuget) in Betracht.

Ex. leicht modifiziert aus der Projektdokumentation:

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

Und innerhalb des EvaluateFunctionDelegaten würden Sie Ihre vorhandene Funktion aufrufen.


0

Tatsächlich arbeite ich an Windows Workflow 4.5 und muss einen Weg finden, einen Delegaten von einer Statemachine an eine Methode ohne Erfolg zu übergeben. Die einzige Möglichkeit, die ich finden konnte, bestand darin, eine Zeichenfolge mit dem Namen der Methode zu übergeben, die ich als Delegat übergeben wollte, und die Zeichenfolge in einen Delegaten innerhalb der Methode zu konvertieren. Sehr schöne Antwort. Vielen Dank. Überprüfen Sie diesen Link https://msdn.microsoft.com/en-us/library/53cz7sc6(v=vs.110).aspx


0
Dieser Code funktioniert in meiner .NET-Konsolenanwendung
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();
    }
}

Willkommen bei SO! Ich mag Ihre Antwort. Können Sie uns etwas näher erläutern, was Sie tun?
a.deshpande012

Hallo, natürlich. Dies ist eine .net-Konsolenanwendung. Innerhalb der "Programmklasse" gibt es verschiedene Methoden oder Funktionen, zum Beispiel: Hallo, Hallo2, Hallo2. Die Methode "CallMethod (string method)" sucht und lässt mich jede Methode innerhalb der "Programmklasse" aufrufen, die von ihrem Namen als String-Parameter aufgerufen wird. Wenn ich die Anwendung über "Windows Console" ausführe: Ich schreibe: "Name App" + "Methode, die ich aufrufen muss". Zum Beispiel: myapp hallo, dann gib "hallo Welt!" Zurück. Könnte auch "myapp hello2" oder "myapp hello3" sein. Ich denke, könnte in jeder .Net-Anwendung funktionieren.
Ranobe

Sie müssen die Reflection-Klasse hinzufügen: "using System.Reflection;".
Ranobe

-9

In C # können Sie Delegaten als Funktionszeiger erstellen. Weitere Informationen zur Verwendung finden Sie im folgenden MSDN-Artikel: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
das ist nicht von Saiten!
Nawfal
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.