1. 表达式树概念

什么是表达式树

表达式树是存储委托的容器,是一种存取Lambda表达式的数据结构;

System.Linq.Expression命名空间下的Expression类和它的诸多子类就是这一数据结构的实现。每个表达式都可以表示成Expression某个子类的实例。每个Expression子类都按照相应表达式的特点储存自己的子节点,也就是 它的每一个子节点都可以表示为一个独立的表达式树。

(用工具可以查看它的body,就是一个树型结构)

表达式树与Lambda

普通Lambda: Func func= (m,n) =>m*n +2;

表达式树: Expression<Func> exp =(m,n)=>m*n +2;

Expression<Func<int, int, int>> exp = (x, y) => x + y;
Func<int, int, int> fun = exp.Compile();
int result = fun(2, 3);

区别

表达式树里面只能由一行,不能写花括号,而Lambda表达式则没有这个限制;

错误代码:

Expression<Func<int,int,int>> func = (m,n)=>{
     return m*n+2;
};

表达式树是数据结构,而Lambda是匿名方法;

转换

int Result1 = func.Invoke(12,23);

int Result2 = exp.Compile().Invoke(12,23);

//exp.Compile() 之后就是一个委托;

如何自己拼装Linq表达式树

既然它是树,它的每个子节点又可以看作一个独立的树,那么我们就可以把一棵树拆分成多个子节点,也可以把一多个子节点拼接成一个树;

例子1

学习编写Expression的方法; 单独写一个类,使用dnSpy 查看源码,然后再自行拼装;

例子2

我们可以看到调用任意一个类的方法是如何做到的

// Add the following directive to your file:
// using System.Linq.Expressions;

// The block expression allows for executing several expressions sequentually.
// When the block expression is executed,
// it returns the value of the last expression in the sequence.
BlockExpression blockExpr = Expression.Block(
    Expression.Call(
        null,
        typeof(Console).GetMethod("Write", new Type[] { typeof(String) }),
        Expression.Constant("Hello ")
       ),
    Expression.Call(
        null,
        typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
        Expression.Constant("World!")
        ),
    Expression.Constant(42)
);

Console.WriteLine("The result of executing the expression tree:");
// The following statement first creates an expression tree,
// then compiles it, and then executes it.
var result = Expression.Lambda<Func<int>>(blockExpr).Compile()();

// Print out the expressions from the block expression.
Console.WriteLine("The expressions from the block expression:");
foreach (var expr in blockExpr.Expressions)
    Console.WriteLine(expr.ToString());

// Print out the result of the tree execution.
Console.WriteLine("The return value of the block expression:");
Console.WriteLine(result);

// This code example produces the following output:
//
// The result of executing the expression tree:
// Hello World!

// The expressions from the block expression:
// Write("Hello ")
// WriteLine("World!")
// 42

// The return value of the block expression:
// 42
posted @ 2020-06-10 17:50  maanshancss  阅读(238)  评论(0编辑  收藏  举报