表达式树是.NET 3.5以后引入的,它是一个壮大天真的东西(比方用在LINQ中组织动态查询)。
先来看看Expression类的API接口:
namespace System.Linq.Expressions { // // 择要: // 以表达式目次树的情势将强范例 lambda 表达式示意为数据结构。此类不能被继续。 // // 范例参数: // TDelegate: // System.Linq.Expressions.Expression`1 示意的托付的范例。 public sealed class Expression<TDelegate> : LambdaExpression { // // 择要: // 将表达式树形貌的 lambda 表达式编译为可执行代码,并生成示意该 lambda 表达式的托付。 // // 返回效果: // 一个 TDelegate 范例的托付,它示意由 System.Linq.Expressions.Expression`1 形貌的已编译的 lambda 表达式。 public TDelegate Compile(); // // 择要: // 生成示意 lambda 表达式的托付。 // // 参数: // debugInfoGenerator: // 编译器用于标记序列点并讲明局部变量的调试信息生成器。 // // 返回效果: // 包括 lambda 的已编译版本的托付。 public TDelegate Compile(DebugInfoGenerator debugInfoGenerator); // // 择要: // 建立一个与此表达式相似的新表达式,但运用所供应的子级。假如一切子级都雷同,则将返回此表达式。 // // 参数: // body: // 效果的 System.Linq.Expressions.LambdaExpression.Body 属性。 // // parameters: // 效果的 System.Linq.Expressions.LambdaExpression.Parameters 属性。 // // 返回效果: // 此表达式(假如未变动任何子级),或带有更新的子级的表达式。 public Expression<TDelegate> Update(Expression body, IEnumerable<ParameterExpression> parameters); protected internal override Expression Accept(ExpressionVisitor visitor); } }
表达式树的语法以下:
Expression<Func<type,returnType>> = (param) => lamdaexpresion;
比方:
Expression<Func<int, int, int>> expr = (x, y) => x+y;
我们运转以上代码,并在VS调试模似下检察这个表达式树:
能够看到表达式树主要由下面四部份构成:
1、Body 主体部份
2、Parameters 参数部份
3、NodeType 节点范例
4、Lambda表达式范例
在上述代码中,主体即为:x+y,参数为(x,y),NodeType为Lambda表达式,返回值为int
主体部份能够是表达式,然则不能包括语句。比方:我定义一个托付,Lambda表达式能够如许写
Func<int, int, int> func = (x, y) => x + y;
也能够如许写:
Func<int, int, int> func = (x, y) => { return x + y; };
然则,在表达式树种,只能用第一种写法,假如运用第二种写法编译报告毛病:没法将具有语句体的 lambda 表达式转换为表达式树。
除了上边的写法,表达式树另有能够这么写:
ParameterExpression pex1 = Expression.Parameter(typeof(int), "x");//第一个参数 ParameterExpression pex2 = Expression.Parameter(typeof(int), "y");//第二个参数 BinaryExpression bexp = Expression.Add(pex1, pex2);//加法 var lambdaExp = Expression.Lambda<Func<int, int, int>>(bexp, new ParameterExpression[] {pex1,pex2 });
VS调试形式下能够看到两种写法生成的表达式树是一样的
将表达式树编译成托付
LambdaExpression是从Expression派生的范例。泛型类Expression<TDelegate>是从LambdaExpression派生的,个中泛型参数TDelegate必需是托付范例。
LambdaExpression有个Compile要领能建立适当范例的一个托付。而Expression<TDelegate>的Compile要领返回TDelegate范例的托付。来看看下面的例子:
Expression<Func<int, int, int>> expr = (x, y) => x + y; ParameterExpression pex1 = Expression.Parameter(typeof(int), "x");//第一个参数 ParameterExpression pex2 = Expression.Parameter(typeof(int), "y");//第二个参数 BinaryExpression bexp = Expression.Add(pex1, pex2);//主体,加法 //运用Expression.Lambda要领,建立一个托付范例已知的Expression Expression<Func<int,int,int>> lambdaExp = Expression.Lambda<Func<int, int, int>>(bexp, new ParameterExpression[] { pex1, pex2 }); Func<int,int,int> tDelegate = lambdaExp.Compile();//编译成托付 Console.WriteLine(tDelegate(1, 3)); Console.Read();
我们运转上面代码,效果为:4。我们写了一大堆代码,本质上就是用表达式树计算了1+3的效果。
以上就是C#中关于表达式树的简朴引见的细致内容,更多请关注ki4网别的相干文章!