我已经阅读了这个答案并从中了解了它突出显示的特定情况,即当您在另一个 lambda 中有一个 lambda 并且您不想意外地让内部 lambda 也与外部 lambda 一起编译时。编译外部的 lambda 表达式时,您希望内部 lambda 表达式保持为表达式树。在那里,是的,引用内部 lambda 表达式是有意义的。
但仅此而已,我相信。还有其他引用 lambda 表达式的用例吗?
如果没有,为什么所有 LINQ 运算符,即在类IQueryable<T>
中声明的扩展都Queryable
引用它们作为参数接收的谓词或 lambda,当它们将信息打包到MethodCallExpression
.
我尝试了一个示例(以及过去几天中的其他几个示例),在这种情况下引用 lambda 似乎没有任何意义。
这是一个方法调用表达式,该方法需要一个 lambda 表达式(而不是委托实例)作为其唯一参数。
MethodCallExpression
然后我通过将它包装在一个 lambda 中来编译它。
但这也不会编译内部LambdaExpression
(GimmeExpression
方法的参数)。它将内部 lambda 表达式保留为表达式树,并且不创建它的委托实例。
事实上,它在不引用它的情况下运行良好。
如果我确实引用了该参数,它会中断并给我一个错误,表明我将错误类型的参数传递给该GimmeExpression
方法。
这是怎么回事?这是什么意思?
private static void TestMethodCallCompilation()
{
var methodInfo = typeof(Program).GetMethod("GimmeExpression",
BindingFlags.NonPublic | BindingFlags.Static);
var lambdaExpression = Expression.Lambda<Func<bool>>(Expression.Constant(true));
var methodCallExpression = Expression.Call(null, methodInfo, lambdaExpression);
var wrapperLambda = Expression.Lambda(methodCallExpression);
wrapperLambda.Compile().DynamicInvoke();
}
private static void GimmeExpression(Expression<Func<bool>> exp)
{
Console.WriteLine(exp.GetType());
Console.WriteLine("Compiling and executing expression...");
Console.WriteLine(exp.Compile().Invoke());
}