Frage

Hier ist, was ich tun möchte, und ich weiß, es möglich ist, mit Perl, PHP, Python und Java, aber ich arbeite mit c #

Wie kann ich wie folgt vor:

public void amethod(string functionName)
{
    AVeryLargeWebServiceWithLotsOfMethodsToCall.getFunctionName();
}

Ich mag die functionName- an die Methode übergeben und ich möchte es, wie oben ausgeführt werden.

Wie kann dies geschehen?

Muss ich ANTLR oder ein anderes Werkzeug für das?

Danke.

War es hilfreich?

Lösung

Sie können eine Methode mit Namen über Reflection auszuführen. Sie müssen die Art, sowie den Namen der Methode kennen (die den aktuellen Objekttyp sein kann, oder ein Verfahren auf einem anderen Objekt oder ein statischer Typ). Es sieht aus wie Sie wollen so etwas wie:

public void amethod(string functionName) 
{
    Type type = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall);
    MethodInfo method = type.GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
    method.Invoke(null,null); // Static methods, with no parameters
}

In Antwort auf Kommentar:

Es klingt wie Sie tatsächlich ein Ergebnis zurück von dieser Methode erhalten möchten. Wenn das der Fall ist, da es immer noch eine statische Methode auf den Dienst (die meine Vermutung ist, gegeben, was Sie geschrieben haben), können Sie dies tun. MethodInfo.Invoke wird die Methode der Rückgabewert als Objekt direkt zurückgeben, so wenn zum Beispiel eine Zeichenkette zurückkehrten, könnten Sie tun:

public string amethod(string functionName) 
{
    Type type = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall);
    MethodInfo method = type.GetMethod(functionName, BindingFlags.Public | BindingFlags.Static);
    object result = method.Invoke(null,null); // Static methods, with no parameters
    if (result == null)
        return string.Empty;
    return result.ToString();
    // Could also be return (int)result;, if it was an integer (boxed to an object), etc.
}

Andere Tipps

Ausführen einer Zeichenfolge als ob es Code ist möglich in c #, aber es ist nicht schön oder einfach. Es ist auch eine schlechte Praxis und unsicher (Sie wahrscheinlich vermeiden sollten es in dynamischen Sprachen, auch) berücksichtigt.

Stattdessen etwas tun, wie folgt aus:

public void amethod(Action actionParam)
{
    actionParam();
}

Nun, in Ihrem Fall, dass Sie einen Web-Service rufen. Da dies letztlich auf xml kommt sowieso haben Sie ein paar Optionen:

  • Bypass das eingebaute System für Web-Service aufrufe und Ihre eigene Web-Anfrage mit dem richtigen Namen an der richtigen Stelle in der XML erstellen.
  • Erstellen Delegierten für jede der Methoden in den Dienst laufen um, möglicherweise über Reflexion.

Wollen Sie damit sagen, dass AVeryLargeWebServiceWithLotsOfMethodsToCall eine Instanz eines Objekts, auf dem Sie eine Methode namens functionName aufrufen wollen? Wenn ja:

MethodInfo method = AVeryLargeWebServiceWithLotsOfMethodsToCall.GetType().GetMethod(functionName);
method.Invoke(AVeryLargerWebServiceWithLotsOfMethodsToCall, null);

Oder ist AVeryLargeWebServiceWithLotsOfMethodsToCall eine Art, auf dem Sie eine statische Methode namens functionName aufrufen wollen? Wenn ja:

MethodInfo method = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall).GetMethod(functionName);
method.Invoke(null, null);

Es kann mit Reflexion erfolgen. Aber ich glaube, dass Sie einen Objektverweis mit ihm zu gehen.

Beispiel von hier

Type t = this.GetType();
MethodInfo method = t.GetMethod("showMessage");
method.Invoke(this, null);

Alternativ können Sie eine Action oder einen anderen Delegierten verwenden, um einen Verweis auf die Funktion, die Sie anrufen möchten, zu übergeben.

public void amethod(Action function)
{
    function();
}

Warum Sie nicht nur .NET Remoting verwenden? Es wird für genau das.

Eine völlig andere Lösung wäre, die CSharpCodeCompiler Klasse zu verwenden.

Hier sind ein paar nützliche Methoden, die Anrufe Klasse und Instanz-Methode übergeben als Strings, optional mit args verarbeiten kann und varargs.

Dies ist kein Produktionscode. Es scheint, zumindest mit diesen trivialen Beispielen zu arbeiten.

class Program
{
    static void Main(string[] args)
    {
        double alpha = Math.Sin(1.0);
        int beta = alpha.CompareTo(1.0);
        Console.WriteLine("{0} {1}", alpha, beta);

        double gamma = (double)CallClassMethod("System.Math.Sin", 1.0);
        int delta = (int)CallInstanceMethod(gamma, "CompareTo", 1.0);
        Console.WriteLine("{0} {1}", gamma, delta);

        string a = "abc";
        string x = "xyz";
        string r = String.Join(",", a, x);
        string s = r.Replace(",", ";");
        Console.WriteLine("{0} {1}", r, s);
        string t = (string)CallClassMethod("System.String.Join", ",", new String[] { a, x }); // Join takes varargs
        string u = (string)CallInstanceMethod(t, "Replace", ",", ";");
        Console.WriteLine("{0} {1}", t, u);
        Console.ReadKey();
    }

    static object CallClassMethod(string command, params object[] args)
    {
        Regex regex = new Regex(@"(.*)\.(\w*)");
        Match match = regex.Match(command);
        string className = match.Groups[1].Value;
        string methodName = match.Groups[2].Value;
        Type type = Type.GetType(className);
        List<Type> argTypeList = new List<Type>();
        foreach (object arg in args) { argTypeList.Add(arg.GetType()); }
        Type[] argTypes = argTypeList.ToArray();
        MethodInfo method = type.GetMethod(methodName, argTypes, null);
        return method.Invoke(null, args);
    }

    static object CallInstanceMethod(object instance, string methodName, params object[] args)
    {
        Type type = instance.GetType();
        List<Type> argTypeList = new List<Type>();
        foreach (object arg in args) { argTypeList.Add(arg.GetType()); }
        Type[] argTypes = argTypeList.ToArray();
        MethodInfo method = type.GetMethod(methodName, argTypes, null);
        return method.Invoke(instance, args);
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top