简体   繁体   English

Expression和Func之间的区别

[英]difference between Expression and Func

What is the difference between Expression and Func? Expression和Func有什么区别? The same task can be attained by both. 两者都可以完成同样的任务。 So what is the difference? 那么区别是什么呢?

Expression trees are data representations of logic - which means they can be examined at execution time by things like LINQ providers. 表达式树是逻辑的数据表示 - 这意味着它们可以在LINQ提供程序之类的执行时进行检查。 They can work out what the code means, and possibly convert it into another form, such as SQL. 他们可以解决代码的含义,并可能将其转换为另一种形式,例如SQL。

The Func family of types, however, are just delegates. 然而, Func系列类型只是代表。 They end up as normal IL, which can be executed directly, but not (easily) examined. 它们最终成为正常的IL,可以直接执行,但不能(轻松)检查。 Note that you can compile expression trees (well, Expression<T> and LambdaExpression ) into delegates and execute those within managed code as well, if you need to. 请注意,如果需要,您可以将表达式树( Expression<T>LambdaExpression )编译到委托中,并在托管代码中执行这些树。

You can build up expression trees manually using the factory methods in the Expression class, but usually you just use the fact that C# can convert lambda expressions into both expression trees and normal delegates: 您可以使用Expression类中的工厂方法手动构建表达式树,但通常只使用C#可以将lambda表达式转换为表达式树和普通委托的事实:

Expression<Func<int, int>> square = x => x * x;
Func<int, int> square = x => x * x;

Note that there are limitations on which lambda expressions can be converted into expression trees. 请注意,可以将lambda表达式转换为表达式树存在限制。 Most importantly, only lambdas consisting of a single expression (rather than a statement body) can be converted: 最重要的是,只能转换由单个表达式(而不是语句体)组成的lambdas:

// Compile-time error
Expression<Func<int, int>> square = x => { return x * x; };
// Works fine
Func<int, int> square = x => { return x * x; };

It is not true that "they do the same thing". “他们做同样的事情”并不是真的。 Expression describes your intent in a way that can be interpreted at runtime - it is, if you like, the recipe. Expression以可以在运行时解释的方式描述您的意图 - 如果您愿意,它就是配方。 A function is an opaque delegate, that can't be inspected - it can be used as a black box. 函数是不透明的委托, 无法检查 - 它可以用作黑盒子。 Compared to a recipe, it is some kind of auto-chef that doesn't let you see what it does: give it some bread and some chicken, close your eyes and it gives you a sandwich, but you never get to know how . 与食谱相比,它是某种自动厨师不会让你看到它的作用:给它一些面包和一些鸡肉,闭上眼睛,它给你一个三明治,但你永远不会知道如何

I discuss this more here: Explaining Expression , but having the recipe is key for LINQ, RPC, etc. And of course, if you have the recipe you can make your own chef, via Expression.Compile() . 我在这里更多地讨论这个: 解释表达式 ,但让配方是LINQ,RPC等的关键。当然,如果你有食谱,你可以通过Expression.Compile()制作自己的厨师。

Expression can be built at runtime, function not (unless you use reflection emit). 表达式可以在运行时构建,不起作用(除非你使用反射发射)。 Once you build the expression tree you can compile it and turn it into a function pointer which can be invoked. 构建表达式树后,您可以编译它并将其转换为可以调用的函数指针。 Func is a pointer to some already existing function which can no longer be modified while Expression represents the code of some function that doesn't exist until you compile it. Func是一个指向一些已经存在的函数的指针,它不能再修改,而Expression表示在编译之前不存在的某些函数的代码。

You usually use expressions when you want to preserve the semantics of the code so that you can translate it. 当您想要保留代码的语义时,通常使用表达式,以便您可以翻译它。 That is, expressions allow you to treat the code as data. 也就是说,表达式允许您将代码视为数据。 If the code does not need to be treated as data (ie you're not planning on storing it or translating it) then using a Func is appropriate. 如果代码不需要被视为数据(即您不打算存储或翻译它),那么使用Func是合适的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM