Ist es möglich, einen Ausdrucksbaum zu erstellen, der direkt eine Methode aufruft? Betrachten wir zum Beispiel die folgende Methode:Erstellen eines Ausdrucksbaums, der eine Methode aufruft
public static int MyFunc(int a, int b)
{
return a + b;
}
Ich möchte ein Ausdrucksbaum erzeugen, die MyFunc mit Parametern a = 1 und b = 2 bezeichnet. Eine Möglichkeit, dies zu tun ist mit Reflexion:
var c1 = Expression.Constant(1);
var c2 = Expression.Constant(2);
var expr = Expression.Call(typeof(Program).GetMethod("MyFunc"), c1, c2);
Dies ist jedoch von Nachteil, weil Reflexion langsam ist und dann auch was kompilieren Zeit sein sollte Fehler in Laufzeitfehler.
kann ich den folgenden Ansatz verwenden, anstatt:
Expression<Func<int, int, int>> lambda = (a, b) => MyFunc(a, b);
var expr = Expression.Invoke(lambda, c1, c2);
Aber das ist immer noch nicht, was ich will, weil es das Verfahren in einem Lambda-Ausdruck hüllt, anstatt es direkt zu nennen.
Eine gute Lösung könnte auf einem Delegierten basieren, wie folgt aus:
Func<int, int, int> del = Program.MyFunc;
var expr = Expression.Invoke(del, c1, c2);
Leider, das nicht kompilieren, weil del
ein Delegierter ist eher als ein Ausdruck. Gibt es eine Möglichkeit, einen Ausdruck von einem Delegaten zu erstellen? (Beachten Sie, dass ich das Ziel des Delegaten zur Kompilierungszeit kenne, so dass ich die hier beschriebene Flexibilität nicht benötige: Expression Trees and Invoking a Delegate.)
Eine nicht delegierte Lösung wäre auch in Ordnung, solange sie anruft die Zielmethode so direkt wie möglich.
Update: Dies funktioniert auch, aber es setzt weiterhin auf Reflexion:
Func<int, int, int> del = Program.MyFunc;
var expr = Expression.Call(del.Method, c1, c2);
Mindestens es wahrscheinlicher ist, Probleme bei der Kompilierung-Zeit zu fangen. Aber es zahlt immer noch den Laufzeitpreis für die Reflexion, nicht wahr?
Weitere Informationen über den Anwendungsfall wären nützlich :) z. Mit den Beispielen, die du angegeben hast, kannst du auch eine einfache 'Func' übergeben ... (und du sagst, dass du das Ziel zur Kompilierzeit kennst). Wozu ist dann der 'Expression'-Baum erforderlich? –
porges
Das Kompilieren eines Ausdrucks wird den Overhead der Reflexion in den Schatten stellen. Da Sie die Reflexion nur einmal ausführen, wenn Sie den Ausdruck machen, werden die Kosten vernachlässigbar sein. – Gabe