C# 4 "dynamique" dans les arbres d'expression
j'essaie de trouver comment rassembler tous les morceaux, et j'apprécierais un échantillon de code source concret pour un cas simple pour commencer.
considère le code C suivant:
Func<int, int, int> f = (x, y) => x + y;
je peux produire une fonction équivalente à l'exécution en utilisant des arbres d'expression comme suit:
var x = Expression.Parameter(typeof(int), "x");
var y = Expression.Parameter(typeof(int), "y");
Func<int, int, int> f =
Expression.Lambda<Func<int, int, int>>(
Expression.Add(x, y),
new[] { x, y }
).Compile();
donne maintenant la lambda suivante:
Func<dynamic, dynamic, dynamic> f = (x, y) => x + y;
comment générer l'équivalent en utilisant des arbres d'expression (et, présumément, Expression.Dynamic
)?
3 réponses
vous pouvez créer une arborescence d'expressions qui représente une expression dynamique C# addition en passant le CallSiteBinder pour une expression dynamique C# addition en Expression.Dynamique. Vous pouvez découvrir le code pour créer le liant en lançant Reflector sur l'expression dynamique originale. Votre exemple serait quelque chose comme ceci:
var x = Expression.Parameter(typeof(object), "x");
var y = Expression.Parameter(typeof(object), "y");
var binder = Binder.BinaryOperation(
CSharpBinderFlags.None, ExpressionType.Add, typeof(Program),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)});
Func<dynamic, dynamic, dynamic> f =
Expression.Lambda<Func<object, object, object>>(
Expression.Dynamic(binder, typeof(object), x, y),
new[] { x, y }
).Compile();
Vous ne pouvez pas le faire parce que une arborescence d'expression "ne Peut pas contenir un fonctionnement dynamique".
ce qui suit ne sera pas compilé, à cause de l'opération+, par exemple, et vous essayez de construire un arbre d'expression qui viole cette règle:
Expression<Func<dynamic, dynamic, dynamic>> f = (x, y) => x + y;
si vous ne faisiez pas D'opération Add, vous pourriez vous en tirer.
Voir Comment créer une Expression
Edit:
C'est aussi proche que possible, en définissant ma propre méthode Add qui prend les paramètres dynamiques et renvoie un résultat dynamique.
class Program
{
static void Main(string[] args)
{
var x = Expression.Parameter(typeof(object), "x");
var y = Expression.Parameter(typeof(object), "y");
Func<dynamic, dynamic, dynamic> f =
Expression.Lambda<Func<dynamic, dynamic, dynamic>>(
Expression.Call(typeof(Program), "Add", null, x, y),
new[] { x, y }
).Compile();
Console.WriteLine(f(5, 2));
Console.ReadKey();
}
public static dynamic Add(dynamic x, dynamic y)
{
return x + y;
}
}
très intéressant. Je suppose que c'est impossible pour la même raison que la suivante ne compile pas:
Expression<Func<dynamic, dynamic, int>> func = (p1, p2) => p1 + p2;
c'est une erreur de compilateur CS1963 (qui ne semble pas être documentée par MS):
erreur CS1963: un arbre d'expression ne peut pas contenir une opération dynamique