表達式樹可以說是Linq的核心之一,為什麼是Linq的核心之一呢?因為表達式樹使得c#不再是僅僅能編譯成IL,我們可以透過c#產生一個表達式樹,將結果作為一個中間格式,在將其轉換成目標平台上的本機語言。比如SQL。我們常用的Linq to sql就是這樣產生SQL的。
表達式樹是.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); } }
表達式樹的語法如下:
Expressioncd1dbc6e985823aa17cbff7e6d77957f> = (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派生的型別。泛型類別Expressiond504b8e2d633d3ab86a819514662e4f9是從LambdaExpression衍生的,其中泛型參數TDelegate必須是委託類型。 ######LambdaExpression有個Compile方法可以創造一個恰當類型的委託。而Expressiond504b8e2d633d3ab86a819514662e4f9的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#中關於表達式樹的簡單介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!