我不认为目前(C# 4.0)可以通过编译器实现这一点,但你当然可以手动使用
Expression.Invoke来完成。
创建一个 InvocationExpression,将委托或 lambda 表达式应用于参数表达式列表。
在你的情况下,它看起来会是这样的:
Expression<Func<int, int>> f = x => x + x;
var parameter = Expression.Parameter(typeof(int),"y");
var body = Expression.Add(Expression.Constant(2), Expression.Invoke(f, parameter));
// Loosely speaking: y => 2 + f(y)
var g = Expression.Lambda<Func<int, int>>(body, parameter);
LINQKit提供了Invoke
/Expand
扩展方法,为您完成了繁琐的工作,使您能够再次使用lambda表达式。这将让您做到:
Expression<Func<int, int>> f = x => x + x;
Expression<Func<int, int>> g = x => 2 + f.Invoke(x);
// Note: 'Inlines' the invocation into the target expression.
var finalExpression = g.Expand();
..这非常接近您最初想要的语法。
关于InvocationExpression
,需要注意的一点是,一些LINQ提供者(如LINQ to Entities)根本不喜欢它们;因此,您经常需要“展开”调用表达式,使其对提供程序看起来像一个单独的表达式。当然,您可以手动完成这个过程,但是LINQKit的AsExpandable
扩展程序再次派上用场。