18 .net c# lambda delegates expression-trees
所以我有一个delegate指向我在第一次创建delegate对象时实际上并不知道的功能.稍后将该对象设置为某个功能.
然后我还想创建一个表达式树,用参数调用委托(为了这个问题,参数可以是5).这是我正在努力的一点点; 下面的代码显示了我想要的内容,但它没有编译.
Func<int, int> func = null;
Expression expr = Expression.Invoke(func, Expression.Constant(5));
Run Code Online (Sandbox Code Playgroud)
对于这个例子,我可以这样做(这是实用的,因为我需要在运行时构建表达式树):
Func<int, int> func = null;
Expression<Func<int>> expr = () => func(5);
Run Code Online (Sandbox Code Playgroud)
这使得expr成为:
() => Invoke(value(Test.Program+<>c__DisplayClass0).func, 5)
Run Code Online (Sandbox Code Playgroud)
这似乎意味着要使用delegate func,我需要产生value(Test.Program+<>c__DisplayClass0).func一点.
那么,我怎样才能创建一个调用委托的表达式树?
Dan*_*ted 14
我想你想要做的是使用委托的Target和Method属性来传递以创建一个Call表达式.基于JulianR的样本,这就是它的样子:
Action<int> func = i => Console.WriteLine(i * i);
var callExpr = Expression.Call(Expression.Constant(func.Target), func.Method, Expression.Constant(5));
var lambdaExpr = Expression.Lambda<Action>(callExpr);
var fn = lambdaExpr.Compile();
fn(); // Prints 25
Run Code Online (Sandbox Code Playgroud)
小智 10
OK,这说明它是如何能够做到(但它是非常不雅的在我看来):
Func<int, int> func = null;
Expression<Func<int, int>> bind = (x) => func(x);
Expression expr = Expression.Invoke(bind, Expression.Constant(5));
Expression<Func<int>> lambda = Expression.Lambda<Func<int>>(expr);
Func<int> compiled = lambda.Compile();
Console.WriteLine(expr);
func = x => 3 * x;
Console.WriteLine(compiled());
func = x => 7 * x;
Console.WriteLine(compiled());
Console.Read();
Run Code Online (Sandbox Code Playgroud)
基本上我(x) => func(x);用来创建一个调用委托指向的函数.但你可以看到这expr太复杂了.出于这个原因,我不认为这个答案很好,但也许可以建立在它的基础之上?