What is the differe开发者_开发问答nce between Expression and 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. They can work out what the code means, and possibly convert it into another form, such as SQL.
The Func
family of types, however, are just delegates. They end up as normal IL, which can be executed directly, but not (easily) examined. 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.
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<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. Most importantly, only lambdas consisting of a single expression (rather than a statement body) can be converted:
// 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. 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()
.
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.
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 (i.e. you're not planning on storing it or translating it) then using a Func is appropriate.
精彩评论