Convert a C # Lambda expression to an Expression Tree

Source: Internet
Author: User

 

As we have seen, lambda expressions can be implicitly or explicitly converted to appropriate delegated instances. however, this is not the only available conversion rule. You can also ask the compiler to help you build an Expression Tree from a Lambda expression and create an expression <tdelegate> instance during execution. for example, the following example uses a more brief method to create a "return 5" expression and then compile and execute the result delegate:

   1: Expression<Func<int>> return5 = () => 5;
   2: Func<int> compiled = return5.Compile();
   3: Console.WriteLine(compiled());

In the first line of code, () => 5 is a Lambda expression. In this example, if we enclose it with parentheses, it will make it look worse or better. note that we do not need any type conversion, and the compiler can help us complete everything. you can write 2 + 3 instead of 5, but the compiler will optimize it (the compiled code is saved as 5 ). it is very important that the lambda expression has been converted to the expression tree.

Limitation-not all lambda expressions can be converted into expression trees. you cannot convert an expression that contains an entire statement (or even only one Return Statement) into an Expression Tree-you can evaluate only one single expression. expressions cannot contain assignments because they cannot be displayed in the Expression Tree. although this is the most common limitation, it is not the only one-it is not worth discussing here because these problems are rarely encountered. and if you try this illegal conversion, the compiler will help you find it in time.

Let's take a look at a more complex example, especially when parameters are introduced. this time, we will write an asserted to determine whether the first of the two input parameters can start with the second parameter. using lambda expressions is still simple:

   1: Expression<Func<string,string,bool>> expression =
   2: ( (x,y) => x.StartsWith(y) );
   3: var compiled = expression.Compile();
   4: Console.WriteLine(compiled("First", "Second"));
   5: Console.WriteLine(compiled("First", "Fir"));

Using the expression tree itself is much more complicated:

   1: MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
   2: var target = Expression.Parameter(typeof(string), "x");
   3: var methodArg = Expression.Parameter(typeof(string), "y");
   4: Expression[] methodArgs = new[] { methodArg };
   5: Expression call = Expression.Call(target, method, methodArgs);
   6: var lambdaParameters = new[] { target, methodArg };
   7: var lambda = Expression.Lambda<Func<string,string,bool>>(call, lambdaParameters);
   8: var compiled = lambda.Compile();
   9: Console.WriteLine(compiled("First", "Second"));
  10: Console.WriteLine(compiled("First", "Fir"));

Although the Code above looks more complex, it clearly shows what is on the Expression Tree and how parameters are bound. let's start with a method call, which forms the subject of the expression: the target of the call method (in other words, the string that calls startswith); the method itself (as methodinfo ); parameter List (in this example, there is only one parameter ). in our example, our method call targets and parameters are passed into the expression as parameters, but they can be other expression types-constants, method call values, attribute values, and so on.

After constructing a method call into an expression, we need to convert it into a Lambda expression and bind it with the required parameters. we reuse the same parameterexpression value created for method calls: the order in which they are specified in lambda expressions is the order in which they are selected by the final call delegate.

Let's take a look at the complex code created above. It's just a simple method call. You can imagine what would happen if it was a more complex expression result-I should be glad that, C #3 You can use lambda expressions to create an Expression Tree. the C #3 compiler creates an expression tree in a similar way, but it has a shortcut: the compiler does not use reflection to obtain a string. startswith's methodinfo, on the contrary, uses the typeof operator equivalent to the method, which is only available in the Il code, and C # is not supported by itself, in addition, the same operator is also applied when the delegated instance is created from the method group.
Now we can see how the Expression Tree and lambda expressions are associated. Let's take a brief look at why they are so useful.

The heart of LINQ-Expression Tree

Without lambda expressions, the expression tree can only have much smaller value. it is just another choice of codedom, especially when you only want to model a single expression rather than a complete statement, method, type, and so on, and the benefits are quite limited.

Likewise, there is no Expression Tree, and lambda expressions are much less useful. it is still very popular to have a more concise way to create a delegated instance, and a more mathematical development method is also feasible. lambda expressions are particularly effective when used with extension methods. however, when combined with the Expression Tree, things become more interesting.

So what do we get when we combine lambda expressions, expression trees, and extension methods? The answer is LINQ. for a long period of time, we have been able to perform great compilation checks. We can also tell another platform to run some code, they are usually plain text (such as SQL queries), but we have never been able to complete them at the same time. lambda expressions provide compile-time check, while the expression tree provides runtime abstraction and binds them together. We have two worlds. the LINQ provider can generate an Expression Tree from a familiar programming language (such as C #) and use it as an intermediate format. It can be converted to a local language on the target platform,
For example, SQL. LINQ to SQL provider allows us to use C # To generate SQL statements.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.