Expression Trees in C# - c#

For the very first time I am exploring expression trees. I have a few basic doubts.
So essentially , an expression takes only a lambda expression . Ans then we can Compile() the lambda expression to MSIL code which in turn returns a generic delegate. We can invoke the returned delegate as it is . Is my understanding correct ?
If it is here is what I am trying to achieve: ((10*5)+(9/4))
BinaryExpression b1 = Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(10), Expression.Constant(5));//(10*5)
BinaryExpression b2 = Expression.MakeBinary(ExpressionType.Divide, Expression.Constant(9), Expression.Constant(4));//(9/4)
BinaryExpression b4 = Expression.MakeBinary(ExpressionType.Add, b1, b2);//((10*5)+(9/4))
So at this point we have made the lambda expression body . Now to turn it to a full lambda expression we need to call
Console.WriteLine(Expression.Lambda<Func<int, int>>(b4).Compile());
I am not getting this part . And this does not work also .
Why this Func<int,int>?
Is it like the inner expressions will take only int as param and the entire expression will return an int?
Obviously this does not work. How the generated lambda looks like ?
I am getting the entire picture? How to make this work?

Expression.Lambda<Func<int, int>>(b4).Compile()
Func<int,int> is a signature for lambdas that take a single int parameter, and return an int. Your lambda has a different signature.
Obviously this does not work.
Your lambda does not take any parameters, so you need Func<int> instead.
How the generated lambda looks like?
Generated lambda is a callable object. If you would like to evaluate the expression that you get back, cast and call it, like this:
var compiledLambda = (Func<int>)Expression.Lambda<Func<int>>(b4).Compile();
Console.WriteLine(compiledLambda());
// ^^
The above prints 52, as expected.
Demo 1.
If you would like to make a Func<int,int>, add a parameter to your expression, e.g. make it (p*5)+(9/4) where p is an int parameter:
ParameterExpression p = Expression.Parameter(typeof(int));
BinaryExpression b1 = Expression.MakeBinary(ExpressionType.Multiply, p, Expression.Constant(5));//(p*5)
BinaryExpression b2 = Expression.MakeBinary(ExpressionType.Divide, Expression.Constant(9), Expression.Constant(4));//(9/4)
BinaryExpression b4 = Expression.MakeBinary(ExpressionType.Add, b1, b2);
var compiledLambda = (Func<int,int>)Expression.Lambda<Func<int,int>>(b4, new[] {p}).Compile();
Console.WriteLine(compiledLambda(10)); // Prints 52
Console.WriteLine(compiledLambda(8)); // Prints 42
Demo 2.

You can create your lambda expression like that:
LambdaExpression lb = Expression.Lambda(b4);
You can then compile this expression to a delegate:
Delegate dlg = lb.Compile();
And cast this delegate to a Func<int>:
Func<int> f = (Func<int>)dlg;
And you can use this as usual:
Console.WriteLine(f()); // 52
The generic way works, too. Why do you use Func<int,int>? Your expression takes no input and returns a single int:
Func<int> f = Expression.Lambda<Func<int>>(b4);
The generic argument leads to a LambdaExpression with a Compile method that returns a Func<int> instead of a Delegate that you'd need to cast again.

Using:
Console.WriteLine(Expression.Lambda<Func<int, int>>(b4).Compile());
you actually print it with Console.WriteLine(object) overload which prints the name of the Type of the argument.
since the line:
Expression.Lambda<Func<int>>(b4).Compile();
only compiles the lambda and provides you the delegate - not its invocation's result.
You need to invoke the compiled lambda and print only the result:
Func<int> result = (Func<int>)Expression.Lambda<Func<int>>(b4).Compile();
Console.WriteLine(result());
Also note that you try to compile the delegate as a Func<int,int> which takes an int argument and provides an int result but your code doesn't require an argument so you need to use Func<int>.

Related

Explain 2 pairs of parentheses in expression.Compile()()

Could you please explain what this strange code does?
expression.Compile()();
Why are there 2 pairs of parentheses here? I didn't find anything in google. The full method is
public Validator NotEmpty(Expression<Func<IEnumerable<T>>> expression)
{
var member = (MemberExpression)expression.Body;
string propertyName = member.Member.Name;
IEnumerable<T> value = expression.Compile()();
if (value == null || !value.Any())
{
ValidationResult.AddError(propertyName, "Shouldn't be empty");
}
return this;
}
It is used like this:
_validator.NotEmpty(() => request.PersonIds); // request.PersonIds is List<int>
This method checks if a collection is empty or null. Everything works fine but I am a little bit confused with that code. I have never seen using 2 pairs of parentheses before in C#. What does it mean?
Well, you pass list of int into the method as expression tree. This expression produces the value of IEnumerable<T> (in this case IEnumerable<int>).
To get value of expression you need to compile this expression into a delegate Func<IEnumerable<T>> and then invoke the delegate.
In fact, I can write two separate lines of code instead of the shorter syntax used above:
Func<IEnumerable<T>> del = expression.Compile();
IEnumerable<T> value = del();
The two brackets () is actually an operator which invokes a method or delegate. See here.
The expression "expression.Compile()" seems to deliver a delegate that can be invoked. The second pair of brackets then invokes this delegate.
You could also rewrite this as:
var del = expression.Compile();
del();

Calling a void-parameter lambda gives compiler error

From this question: Lambda expression with a void input
I have the following very simple code:
int minutes = () => 9;
I get compiler error:
Cannot convert lambda expression to type 'int' because it is not a
delegate type
I've found several questions about this error but they're all about more specific issues. I actually want to give my lambda a body but thought I'd start simple first to check my syntax:
//I know this is a weird example
int minutes = ()=> { if(x==9) return 9; else return 5;}
From C# guide
A lambda expression is a block of code (an expression or a statement block) that is treated as an object. It can be passed as an argument to methods, and it can also be returned by method calls.
...
Lambda expressions are code that can be represented either as a delegate, or as an expression tree that compiles to a delegate.
That means lambda expression can be represented and can represent different things: delegate or expression tree.
Your expression
() => 9;
can be so many different things, as example
public class C {
delegate int IntDelegate();
public void M() {
Func<int> minutes = () => 9;
IntDelegate minutes2 = () => 9;
Expression<Func<int>> minutesExpression = () => 9;
Expression<IntDelegate> minutesExpression2 = () => 9;
}
}
So what do you want to use?
By the way, because of all that, you can't use var with them.
And you can see how c# compiler work under the hood for different lambda here-> lambda as delegate and expression tree

Lambda Expression definition (pedant )?

By just briefing a book (leading one) , one thing caught my eyes - the lambda expression definition :
A lambda expression is an unnamed method written in place of a
delegate instance.
in place of delegate instance ???
A delegate instance is an object that refers-to/encapsulate target method/s :
In the following sample The right side(where the lambda expression would be) is not a delegate instance. it is a method.
TransformerDelegate t = SquareMethod;
So the definition should have been corrected-to/mention :
lambda expression are unnamed method written in place of a method(!)
being referenced by delegate variable.
TransformerDelegate sqr = x => x * x;
^
|
---------------+
|
this is the location for method/anonymous methods.
do you see what I mean ? Am I right?
p.s. I did understand the msdn's one : ( but want to see if the book had made a mistake)
A lambda expression is an anonymous function that can contain
expressions and statements, and can be used to create delegates or
expression tree types.
The value of a lambda expression is a delegate instance.
So the book is probably referring to code like:
MySquareDelegate f1 = x => x * x;
MySquareDelegate f2 = new MySquareDelegate(MySquareMethod);
MySquareDelegate f3 = MySquareMethod; // just shorthand for the previous line
It is tricky stuff to explain in 1 sentence, your own version
lambda expression are unnamed method written in place of a method(!) being referenced by delegate variable.
is talking about "a method instead of a method", the original about "a method instead of a delegate instance" where the method is implicitly converted to a delegate instance. Both seem incomplete at least.
A definition of a lambda should also include that it is an inline method.
Other answers miss the fact that lambda expressions do not necessarily represent methods. Sometimes, they represent expression trees.
The compiler implicitly converts lambda expressions to one type of object or the other, depending on context.
To specify a method, you need to specify parameters and a body. In a lambda expression, these are separated by =>. Examples:
() => 4; //empty parameter list
x => x.ToString(); //one parameter
(a, b) => a.Equals(b); //two parameters
// ^^^^^^ ^^^^^^^^^^^^
// | |
// parameter list body
These lambda expressions can be converted to Func<int>, Func<object, string>, and Func<object, object, bool> respectively. The could also be converted to Expression<Func<int>>, Expression<Func<object, string>>, and Expression<Func<object, object, bool>> respectively.
An anonymous method:
delegate (object p, object q) { return string.Concat(p, q); }
// ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// parameter list body
Here are two examples of lambda conversion:
Func<object, object, bool> aDelegate = (o1, o2) => object.Equals(o1, o2);
Expression<Func<object, object, bool>> anExpressionTree = (o1, o2) => object.Equals(o1, o2);
In method group conversion, the parameters and method body are specified by overload resolution. To simplify a bit, the compiler looks at the methods with the indicated name and chooses the correct overload based on the context. For example, consider these overloads of SquareMethod:
int SquareMethod(int a) { return a * a; }
double SquareMethod(double a) { return a * a; }
These statements involve method group conversion and overload resolution:
Func<int, int> squareAnInt = SquareMethod;
Func<double, double> squareADouble = SquareMethod;
Finally, statement lambdas cannot be translated to expression trees:
Action<object> anAction = o => { Console.WriteLine(o); };
Func<object, int> aFunc = o =>
{
var s = (o ?? "").ToString();
Console.WriteLine(s);
return s.Length;
};
The C# language specification (somewhat confusingly) uses the term "anonymous function" to cover both lambda expressions and anonymous methods. Anonymous functions can be implicitly converted to a compatible delegate type, and so can method groups. Therefore, if we have a delegate type called DelegateType, and a declaration/assignment like this:
DelegateType d = [something];
Then [something] can be a method group or an anonymous function. In other words, it can be a method group, an anonymous method or a lambda expression.
So, your correction to the book's text would be better to say "in place of a method group", but I would say
A lambda expression is an unnamed method that, like a named method group, can be used to create a delegate instance.
I might also add
In some cases, a lambda expression can be used to create an expression tree rather than a delegate instance.
Basically a delegate is nothing but an object that knows how to call a specific method. So a delegate instance literally acts as a delegate for the caller: the caller invokes the delegate, and then the delegate calls the target method.

what is the use of ()=> in silverllight

Can you say what is the use of the ()=> and =>? I saw this in a code. I did not get any reference for this.
this.Dispatcher.BeginInvoke(()=>
{
//some thing..
};
=> is the lambda operator in C# and is read as "goes to". A lambda expression is an anonymous function and can be used to create a delegate.
Your example takes no arguments as indicated by the empty parens preceding the lambda operator. A lambda expression with one argument might look like this:
n => n.toString()
That expression would return the string representation of n, when invoked. A lambda expression can have multiple arguments as well, contained in parentheses:
(n, f) => n.toString(f)
A common use would be in a Func<T>:
Func<int, string> getString = n => n.toString();
int num = 7;
string numString = getString(num);
This is, of course, a silly example, but hopefully helps to illustrate its use.
This notation is that of a lambda expression which takes no argument. If the lambda expression made use of arguments they would be declared in the empty set of parenthesis as in say...
this.Dispatcher.BeginInvoke((x, y) => { do some' with x and/or y }, 12, somevar);
In a nutshell, lambda expressions allows creating "nameless" functions, right where they are needed.
In the example of the question, the BeginInvoke() method requires its first parameter to be a delegate (a "pointer to a method"), which is exactly what this lambda expression provides.
It's a lambda expression that has no parameters.
Check out this page http://codebetter.com/karlseguin/2008/11/27/back-to-basics-delegates-anonymous-methods-and-lambda-expressions/
If you don’t have any parameters, like in our example, you use empty
paranthesis:
() => {…}

Lambda to Expression tree conversion

I will keep it really simple,
How do I get expression tree out of lambda??
or from query expression ?
You must assign the lambda to a different type:
// Gives you a delegate:
Func<int, int> f = x => x * 2;
// Gives you an expression tree:
Expression<Func<int, int>> g = x => x * 2;
The same goes for method arguments. However, once you've assigned such a lambda expression to a Func<> type, you can't get the expression tree back.
Konrad's reply is exact. You need to assign the lambda expression to Expression<Func<...>> in order for the compiler to generate the expression tree. If you get a lambda as a Func<...>, Action<...> or other delegate type, all you have is a bunch of IL instructions.
If you really need to be able to convert an IL-compiled lambda back into an expression tree, you'd have to decompile it (e.g. do what Lutz Roeder's Reflector tool does). I'd suggest having a look at the Cecil library, which provides advanced IL manipulation support and could save you quite some time.
Just to expand on Konrad's answer, and to correct Pierre, you can still generate an Expression from an IL-compiled lambda, though it's not terribly elegant. Augmenting Konrad's example:
// Gives you a lambda:
Func<int, int> f = x => x * 2;
// Gives you an expression tree:
Expression<Func<int, int>> g = x => f(x);

Categories

Resources