1

I've just come across Expression trees and I found that its is better to use them with LINQ than just Func<T, Boolean>. However, I found that I can't directly pass an Expression to a LINQ method, let's say the Select method. But I found that there is a Compile method associated with the Expression that converts it to a normal Func. Now I've been wondering, is it the right way to call an Expression at all (by using the Compile method), and if so then what would be the difference between a Func and an Expression. If it is not the right way then how to use it, for example passing this:

Expression<Func<T, Bool>> Test

to

Data.Where(Test) --> Test can't be passed to it directly 
James
  • 143
  • 1
  • 9
  • 3
    what is your question? It's not clear. – DLeh Mar 04 '15 at 20:46
  • @DLeh: I just found out that there's something called as Expression, I know what they are, let's say you have declared one (as a parameter in a method) and you wanna pass it to a LINQ query, do you call the expression's Compile method to do so or is there any special way to handle them? – James Mar 04 '15 at 20:48
  • how about post some real example code instead of making us try to imagine what you're talking about – DLeh Mar 04 '15 at 20:49
  • @DLeh: It's not that hard, for example `public T Get (Expression> Selector)`, and how do you use the Selector in a LINQ query. – James Mar 04 '15 at 20:50
  • 1
    I don't know how Expression trees are better unless you are talking about `IQueryable`, but then the Linq extension methods for that do take Expression trees, for a reason. Do you have a reason for using them? – juharr Mar 04 '15 at 20:51
  • 1
    Below link also have a lot of detail about this topic. [http://stackoverflow.com/questions/793571/why-would-you-use-expressionfunct-rather-than-funct][1] [1]: http://stackoverflow.com/questions/793571/why-would-you-use-expressionfunct-rather-than-funct – Gaurav Sharma Mar 04 '15 at 20:51
  • @James An `Expression` is a representation of the constituent elements of some chunk of high level (e.g. C#) code. A `Func` on the other hand is a representation of some callable method that accepts some inputs and returns an output; a `Func` is unaware of what C# constructs went into its creation. If you're working with an API that needs to examine an abstract representation of a chunk of code, it will probably ask for an `Expression`. If you're working with an API that needs a callable that takes some inputs and produces an output, you need to give it a `Func`. – Asad Saeeduddin Mar 04 '15 at 20:57

2 Answers2

6

Using Expression vs Func really depends on your use case and which Linq provider you are using.

If you are using Entity Framework, Linq to SQL, or any other query provider that translates expression trees into some other query language then you have to use Expression.

If you are using Linq to Objects, then you have a choice. Usually you would want to use Func directly, without first creating an expression then compiling it.

You might use Expression if what you are doing requires building arbitrary and complex queries at runtime. In this case you would call compile before executing the query. The common example of this would users providing complex search queries through a UI.

Chris Pitman
  • 12,990
  • 3
  • 41
  • 56
  • Thanks Chris, so, Let's say we have a ParallelQuery, and the extension method for this type such as the select do not use expression, so there's no need to pass expressions into such methods and compile it, is that right? and then on the other hand, when dealing with IQuerable then expression is a better move ? – James Mar 04 '15 at 20:56
  • Good answer, one thing to clarify is that using expression trees with Entity Framework is optional and only required for dynamic queries (as pointed out in the last paragraph). I would avoid it if you can. – PermaFrost Mar 04 '15 at 21:04
  • @PermaFrost: What do you mean "I would avoid it if you can"? You mean using Expressions ? – James Mar 04 '15 at 21:07
  • 2
    @PermaFrost I'm pretty sure using expression trees with Entity Framework is 90% of the value of the library. The translation from lambdas to SQL cannot work without EF examining the lambda's expression tree. It isn't some niche feature. – Asad Saeeduddin Mar 04 '15 at 21:08
  • @James Right, you are almost always better off using the same type as the provider requires. There are *some* cases where you would use an `Expression` when you need a `Func`, but they are limited to dynamically modifying the expression trees (ie really advanced, you'll know you need it). – Chris Pitman Mar 04 '15 at 22:55
  • @Asad You are right that Entity Framework's query provider implementation has to look at expression trees even if you are not passing them in. That's just how it has to operate under the hood. @Asad, @James: Yes, I meant avoiding expressions. Why? Because it's an additional level of complexity vs. using `Func` directly and I would skip it if not required (e.g. you're not having "dynamic needs"). I doubt there is a big performance gain when you use `Expression` instead of `Func` when working with EF, but have never measured it. – PermaFrost Mar 05 '15 at 10:59
  • 1
    @PermaFrost But you are passing them in. When I do `myContext.Users.Where(u => u.FirstName == "Asad")`, the lambda expression I'm passing in is an instance of `Expression`. – Asad Saeeduddin Mar 05 '15 at 12:22
  • @Asad You are right, sorry about the confusion. I actually thought code such as this would not use the method overload with `Expression` parameters, but the `Func` overload but that's not true as you pointed out (Visual Studio also thinks that way ;-)). – PermaFrost Mar 05 '15 at 15:09
2

Basically, an expression tree is a data structure which may be compiled into executable code or not.

Some methods require you to provide expression trees because they need to analyze what's inside the expression so it takes decisions based on this. Also, LINQ providers which execute these expressions against data sources like SQL, analyze them to translate your code to a particular SQL dialect.

In the above case, the expression tree never gets compiled.

Furthermore, you don't want to go with the expression trees' route to solve any problem if you're not building a possible executable code based on conditions and use cases. If you just declare expression trees because you find them powerful you're not in the right way, because you're adding an extra overhead of compiling them to delegates to make them executable...

I would also add that expression trees are very powerful because it's practically like building C# code using abstract syntax trees (AST), while regular language compilation flow is translating human programming languages like C# into an AST, then into intermediate languages or machine code. In other words, it's like having a run-time compiler.

In the .NET early days, this was only possible using reflection emit, Mono Cecil or other intermediate language weavers, and just imagine how you would write something like () => "hello world" using .NET intermediate language...!

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206