Expression trees in C #

The first time I study expression trees. I have a few basic doubts.

Essentially, an expression accepts only a lambda expression. Ans, then we can compile () the lambda expression for the MSIL code, which in turn returns a common delegate. We can call the returned delegate as is. Do I understand correctly?

If this is exactly what I'm 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 that moment we did lambda expression body. Now, to turn it into full lambda expression, we need to call

Console.WriteLine(Expression.Lambda<Func<int, int>>(b4).Compile());

I do not get this part. And that also does not work.

Why is this Func<int,int>?

It seems that the internal expressions will only accept int as param, and the whole expression will return int?

Obviously this does not work. What does the generated lambda look like?

Am I getting the whole picture? How to do it?

+4
3
Expression.Lambda<Func<int, int>>(b4).Compile()

Func<int,int> lambdas, int int. .

, .

, Func<int>.

?

. , , , :

var compiledLambda = (Func<int>)Expression.Lambda<Func<int>>(b4).Compile();
Console.WriteLine(compiledLambda());
//                              ^^

52, .

1.

Func<int,int>, , . (p*5)+(9/4), p int:

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

2.

+6

:

LambdaExpression lb = Expression.Lambda(b4);

:

Delegate dlg = lb.Compile();

Func<int>:

Func<int> f = (Func<int>)dlg;

:

Console.WriteLine(f()); // 52

. Func<int,int>? int:

Func<int> f = Expression.Lambda<Func<int>>(b4);

LambdaExpression Compile, Func<int> Delegate, .

+4

:

Console.WriteLine(Expression.Lambda<Func<int, int>>(b4).Compile());

Console.WriteLine(object) , Type .

:

Expression.Lambda<Func<int>>(b4).Compile();

, delegate - .

You need to call 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 are trying to compile delegateas Func<int,int>, which takes an argument intand provides the result int, but your code does not require an argument, so you need to use Func<int>.

+1
source

Source: https://habr.com/ru/post/1664461/


All Articles