Ste*_*fen 55 c# lambda expression-trees
我想知道在内部包装代表之间究竟有什么区别Expression<>?
我看到Expression<Foo>LinQ使用了很多,但到目前为止,我还没有找到任何解释它之间差异的文章,只是使用了一个委托.
例如
Func<int, bool> Is42 = (value) => value == 42;
Run Code Online (Sandbox Code Playgroud)
与
Expression<Func<int, bool>> Is42 = (value) => value == 42;
Run Code Online (Sandbox Code Playgroud)
    Jef*_*ado 63
通过将lambda存储为委托,您将存储执行某些操作的委托的特定实例.它无法修改,你只需要调用它.一旦你有了你的代表,你在检查它的功能和诸如此类的东西方面的选择有限.
通过将lambda存储为表达式,您将存储表示委托的表达式树.它可以被操纵来做其他事情,比如改变它的参数,改变身体并让它做一些截然不同的事情.它甚至可以编译回代表,所以如果你愿意,你可以打电话给代表.您可以轻松地检查表达式,以查看其参数是什么,它做了什么以及如何做.这是查询提供程序可以用来理解表达式并将其转换为另一种语言(例如为相应的表达式树编写SQL查询).
使用表达式动态创建委托比发出代码要容易得多.您可以将更高级别的代码视为与编译器查看代码而非低级别并将代码视为IL指令非常相似的表达式.
因此,使用表达式,您可以比简单的匿名委托做更多的事情.虽然它不是真正免费的,但如果你运行编译表达式与常规方法或匿名委托相比,性能将受到影响.但这可能不是问题,因为使用表达式的其他好处对您来说可能很重要.
Uco*_*dia 12
为了说明其他答案,如果您编译这两个表达式并查看编译器生成的代码,那么您将看到:
Func<int, bool> Is42 = (value) => value == 42;
Func<int, bool> Is42 = new Func<int, bool>((@value) => value == 42);
Run Code Online (Sandbox Code Playgroud)
Expression<Func<int, bool>> Is42 = (value) => value == 42;
ParameterExpression[] parameterExpressionArray;
ParameterExpression parameterExpression = Expression.Parameter(typeof(int), "value");
Expression<Func<int, bool>> Is42 = Expression.Lambda<Func<int, bool>>(Expression.Equal(parameterExpression, Expression.Constant(42, typeof(int))), new ParameterExpression[] { parameterExpression });
Run Code Online (Sandbox Code Playgroud)