1

Expression trees purpose:

Expression tree must be compiled before it can be used. This is because expression tree is actually a data structure, not compiled code. Why? Because this code is expected to be used across wire, or – in other words – in other processes (running possibly on other computers).

From: http://geekswithblogs.net/Martinez/archive/2009/06/29/understanding-expression-trees.aspx

What is the difference between 'Data Structure' and 'compiled code'; How does comipled code looks like in C# ?! By this article I understand that every line that does not contain Array or List is compiled code (Like: "Human H1=new Human(18);").

Please dont expain me what are Expression trees with examples, I want a clear answer about this question.

Thank you for your time

Community
  • 1
  • 1
Stav Alfi
  • 13,139
  • 23
  • 99
  • 171
  • Are you asking what is the difference between C# source and IL code? – jcolebrand Oct 25 '12 at 14:48
  • If so, I recommend you to download ILSpy and look at the sources of a common module in both C# and IL. – jcolebrand Oct 25 '12 at 14:48
  • 1
    `Please dont expain me what are Expression trees with examples` You realize that's basically what your question is. In order to answer this question one would need to know, in detail, what expression trees are and how they work. – Servy Oct 25 '12 at 14:52
  • 1
    I cant understand it becouse the article's writer use defenition that i dont know. – Stav Alfi Oct 25 '12 at 14:55

5 Answers5

3

You cannot execute an expression tree without compiling it first because expression trees serve a different purpose: they work as flexible blueprints for executable code, rather than being the the executable code itself (with is rather inflexible).

An expression tree is a data structure that describes code (compiled or not) at an abstraction level that is higher than the code itself. Unlike code, the data structure can be manipulated to make a different structure that describes some other piece of code. Unlike the data structure, the code can be evaluated to produce a result.

Consider this example:

Expression p1 = Expression.Parameter(typeof(int), "a");
Expression p2 = Expression.Parameter(typeof(int), "b");
Expression expr = Expression.Add(p1, p2);

It shows an expression expr being created, describing a simple expression tree a+b. At this point, we have a tree-like data structure with three nodes - two nodes representing parameters, and one node representing addition. We can do lots of things with the expression tree, such as examining its content, finding its return type, and so on. We can even manipulate its structure to make other expressions based on it: for example, we could add a third parameter, and make a+b+c, like this:

Expression p3 = Expression.Parameter(typeof(int), "c");
expr = Expression.Add(expr, p3);

One thing we cannot do, however, is pass it two integer values and obtain their sum: expression trees do not provide methods for evaluating them. In order to do that, you need real code, not a description of code.

Expression trees provide a way to convert descriptions of code into code by way of compiling them. Once you make an expression tree into lambda and call the Compile() method on it, you get back a compiled CIL code that looks like this:

ldarg.0
ldarg.1
add
ret

This code can be passed two values for evaluation, and it will return the sum to you. However, some information is lost in translation: specifically, the names of parameters a and b are no longer there in the compiled code: they are not necessary to perform calculations, so they have been eliminated.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Thank you. You described it so good that I understood it perfectly with my poor english. Thank you agian. – Stav Alfi Oct 25 '12 at 15:21
  • In the future, to see this "magically" you can use ILSpy and translate between C# and IL. – jcolebrand Oct 25 '12 at 15:44
  • One thing you didnt say, Why Should I prefer using expressions in LINQ to Entity/SQL and not compiled code? Why it is more easy to aother prossesor to read the expressions then compiled code? – Stav Alfi Oct 25 '12 at 20:20
  • 1
    @StavAlfi If you can use a piece of compiled code, you should always prefer a piece of compiled code. There are two situations when you cannot do it: (1) when you need to examine the structure of the expression, such as in LINQ2SQL/EF, or (2) when you do not know the expression at compile time. The (1) is not possible because there is no API for examining the structure of compiled code; (2) us desirable when the expression is built dynamically from user input, configuration, or other information passed to you only at run time. – Sergey Kalinichenko Oct 25 '12 at 20:33
2

You have to read that statement in the context it was written: an expression tree is a data structure, so the expression it represents cannot be evaluated until the expression tree is compiled.

Let's put it this way: the expression below will get compiled when you build your project. However, all that's going to happen when you run your application is that it will build an expression tree (i.e. a data structure).

Expression<Func<int, int, bool>> f = (a, b) => a < b;

In order to actually execute the expression f, you have to compile it f.Compile(). Note that there are two compiles occurring:

  • The 1st compile is when you compile your code (i.e. what's shown above).
  • Th 2nd compile is when you run your code and the actually expression represented by the tree is compiled.

Update

Why cant I excute it without f.Compile() ? THIS is what i realy ask

The Expression.Compile method "compiles the lambda expression described by the expression tree into executable code..." If you don't have executable code, then you can't execute the expression tree. This is no different than asking why you can't execute your program until you compile it.

Kiril
  • 39,672
  • 31
  • 167
  • 226
  • Why cant I use compiled code across wire, or – in other words – in other processes? – Stav Alfi Oct 25 '12 at 14:58
  • Why cant I excute it without f.Compile() ? THIS is what i realy ask – Stav Alfi Oct 25 '12 at 15:00
  • 1
    @StavAlfi for the same reason that you can't execute your program until it is compiled: there is nothing to execute. When you compile your expression tree, then there is something to execute (i.e. machine instructions). – Kiril Oct 25 '12 at 15:02
2

In C#, the "compiled code" from your C# source code is so-called IL (intermediate language) code. (This is similar to Java bytecode.) It's also known as CIL (Common Intermediate Language) per the official standard. (MSIL means the same, it's Microsoft's implementation of CIL.)

Of course, when your .NET application is run, this IL code will get further translated to native code (machine code) by the CLR (Common Language Runtime, the virtual machine of .NET). (In certain cases, IL code is compiled to native code at install time, e.g. the .NET assemblies such as mscorlib.dll in your Windows are compiled in advance; this is called NGEN i.e. native image generation.)

When the article mentions data structures, it means that your Expression Tree expressions themselves are not compiled (at your application's compile time) to IL code in the same way as your "usual" C# expressions or instructions. Instead, even in IL code, they remain data (don't forget: your "usual" expressions become instructions in the IL code, because they are translated by your C# compiler at compile time to direct IL code). Later, they can be asked (explicitly) to be compiled, i.e. the trees will be evaluated (compiled) at run time. Until that point, they remain data structures.

Another approach of the same matter: your C# source code has a well-defined syntax, right? When your C# compiler parses and compiles it, it also needs to parse all your expressions (the "usual" ones, i.e. forget about Expression Trees here). For example, when it parses x = y + 5*z;, it needs to build its own tree from this data, but this happens only internally in your C# compiler at compile time. When it's done, i.e. for example your Visual Studio says "Build succeeded", then your IL code was generated i.e. your application was built. During this build process, the C# compiler also used trees and such structures for expressions.

Now you can look at Expression Trees in a very similar way: they represent an expression in a tree structure, but these Trees are available in your application and can be compiled at run time (unlike the internal tree structures of your C# compiler, which are used internally while your application is built, and will be discarded once your application is built.)

Thomas Calc
  • 2,994
  • 3
  • 30
  • 56
1

Expression Trees (the data structure) can be considered the metadata about the code being represented by the lambda or code. Expression trees get compiled into executable code (the lambda). Expression Trees are Abstract Syntax Trees (AST) -- it is an object that represents the structure of the code you want to execute. (Ugly Details Here)

So, to answer your question, expression trees are metadata (which I guess you could consider a data structure) and the lambda is the actual bits that can be executed.

The purpose of Expression Trees, in my opinion, is not what your referenced article maintains. In my opinion, Expression Trees allow you to compose lambdas (or code) in your code, so that your LINQ statements (or other code) can be flexible and dynamic. I don't think it really comes down to transmitting your structure over the wire. I guess that can be a use of it, but a very useful purpose of Expression Trees, again in my opinion, is the composition of functioning code.

I hope this helps.

David Hoerster
  • 28,421
  • 8
  • 67
  • 102
0

Those two concepts are very distinct and it's unclear what measure you want to compare them against. It's like asking what's a difference between apple and love...

  • Data structure is a concept of how the data is modelled and stored.

  • Compiled code is an atrifact which is the result of compilation.

You can write code that implements certain data structure and them compile it.

Jakub Konecki
  • 45,581
  • 7
  • 87
  • 126