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操作