程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#高級程序設計(九)——表達式樹

C#高級程序設計(九)——表達式樹

編輯:C#入門知識

表達式樹的設計是基於"code as data"的思想,它把代碼表示成樹狀的數據結構,樹狀結構中的每個節點都是一個表達式(這個表達式是一個廣義的概念,並不是編程語言中所指的表達式語法),因此稱為表達式樹。
表達式樹的本質在於將代碼組織在數據段,而不是代碼段,這對於運行時更改代碼是非常重要的。
System.Linq.Expressions命名空間下含有很多類來表示不同的表達式,這些類都繼承自抽象的Expression基類,Expression含有豐富的靜態方法用於創建各種各樣的表達式類。
一、編程方式構建表達式樹
下面的代碼以編程的方式構建表達式樹
[csharp] 
Expression firstArg = Expression.Constant(2); 
Expression secondArg = Expression.Constant(3); 
Expression add = Expression.Add(firstArg, secondArg); 
Console.WriteLine(add); 

上面的代碼創建的表達式樹如圖:
\

二、表達式樹與代理(編譯表達式樹成為代理)
將表達式樹轉化為代理的關鍵點在於Expression<TDelegate>類,繼承關系如圖:
\

可以使用Expression.Lambda方法創建Expression<TDelegate>對象,Expression<TDelegate>對象包含Compile方法,用於將表達式編譯成可執行代碼並生成表示其lambda表達式的代理對象,
下面的代碼表示轉換過程:
[csharp] 
Expression firstArg = Expression.Constant(2); 
Expression secondArg = Expression.Constant(3); 
Expression add = Expression.Add(firstArg, secondArg); 
Func<int> compiled = Expression.Lambda<Func<int>>(add).Compile(); 
Console.WriteLine(compiled()); 

三、表達式樹與Lambda表達式(Lambda表達式轉換為表達式樹)
可以通過lambda表達式構造Expression<TDelegate>對象:
[csharp] 
Expression<Func<string, string, bool>> expression = 
(x, y) => x.StartsWith(y); 
var compiled = expression.Compile(); 
Console.WriteLine(compiled("First", "Second")); 
Console.WriteLine(compiled("First", "Fir")); 

下面的代碼與之等價,但是用編程方式構建表達式樹:
[csharp]  
MethodInfo method = typeof(string).GetMethod 
("StartsWith", new[] { typeof(string) }); 
var target = Expression.Parameter(typeof(string), "x"); 
var methodArg = Expression.Parameter(typeof(string), "y"); 
Expression[] methodArgs = new[] { methodArg }; 
Expression call = Expression.Call(target, method, methodArgs); 
var lambdaParameters = new[] { target, methodArg }; 
var lambda = Expression.Lambda<Func<string, string, bool>> 
(call, lambdaParameters); 
var compiled = lambda.Compile(); 
Console.WriteLine(compiled("First", "Second")); 
Console.WriteLine(compiled("First", "Fir")); 

目前,並不是所有的lambda表達式都能轉換成表達式樹,只有單一表達式的lambda表達式才可以轉化為表達式樹,而且表達式中不能包含賦值。

四、表達式樹與LINQ
表達式樹主要應用在LINQ to SQL中,LINQ to SQL的目標是將LINQ請求轉換為SQL語句(普通文本),但是在轉換過程中我們又不想失去編譯時類型檢查,所以LINQ to SQL的設計思想是將LINQ查詢轉化成表達式樹(查詢中使用的lambda表達式按照某種算法轉換為表達式樹),然後再將表達式樹轉換成需要執行的SQL語句。
\

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved