expression式树中的C#4“dynamic”

我试图弄清楚如何把所有的东西放在一起,并希望一个简单的情况下具体的源代码示例开始。

考虑下面的C#代码:

Func<int, int, int> f = (x, y) => x + y; 

我可以在运行时使用expression式树生成一个等价的函数,如下所示:

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

现在给出下面的lambda:

 Func<dynamic, dynamic, dynamic> f = (x, y) => x + y; 

我将如何生成等效使用expression式树(和大概, Expression.Dynamic )?

通过将dynamicC#添加expression式的CallSiteBinder传递到Expression.Dynamic中,您可以创build表示dynamicC#添加expression式的expression式树。 您可以通过在原始dynamicexpression式上运行Reflector来发现代码以创build活页夹。 你的例子会像这样:

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

你不能这样做,因为expression式树“可能不包含dynamic操作”。

例如,下面的代码就不会编译,因为你正在试图构build一个违反这个规则的expression式树:

  Expression<Func<dynamic, dynamic, dynamic>> f = (x, y) => x + y; 

如果你没有做一个添加操作,你可以逃避它。

请参阅如何创buildexpression式<Func <dynamic,dynamic >> – 或者是一个错误? 了解更多信息。

编辑:

这是尽可能接近,通过定义我自己的添加方法,采取dynamic参数,并返回一个dynamic的结果。

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

很有意思。 我想这是不可能的,同样的原因下面不编译:

 Expression<Func<dynamic, dynamic, int>> func = (p1, p2) => p1 + p2; 

这是一个编译器错误CS1963(似乎没有logging的MS):

错误CS1963:expression式树可能不包含dynamic操作