動態生成C# Lambda表達式


轉載:http://www.educity.cn/develop/1407905.html,並整理!

 

  對於C# Lambda的理解我們在之前的文章中已經講述過了,那么作為Delegate的進化使用,為了讓代碼簡潔和優雅的呈現,C# Lambda表達式的使用功不可滅,那么依托外部條件如何動態構建C# Lambda表達式呢。下面讓我們來具體的看看實施。

  或許你會奇怪這個需求是如何產生的…… 首先,Lambda 在 DLinq 中承擔了以往 T-SQL 的部分角色;其次,在數據庫設計中,我們往往需要依據外部未知的動態條件組合來查詢數據。而問題在於作為一種靜態語言,我們顯然無法用動態語法或者拼接字符串的方法來創建一個Delegate/Lambda,那么如何達到類似的目的呢?CodeDom?Emit?或許最佳的選擇是 System.Linq.Expressions.Expression。

 

1、首先我們了解一個簡單C# Lambda表達式的構成。

i => i > 5 

  在這個表達式中,"i" 被稱為 Parameter,"i > 5" 是 Body。我們可以對 Body 進行更進一步的分解,那么 "i > 5" 分別包含參數(i)、操作符(>)以及一個常數(5)。所有這些通過特定順序的組合,從而構建一個完整的 Lambda 表達式。

2、我們通過一些例子,來學習如何動態構建C# Lambda表達式。

  動態構建C# Lambda表達式例子①

  1、准備例子

var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

  2、要實現的表達式 

var r = ints.Where(i => i > 5);   

  3、動態創建該表達式具體代碼

// 創建參數 i  
var parameter =   
Expression.Parameter(typeof(int), "i");  
   
// 創建常量5  
var constant =   
Expression.Constant(5);  
   
// 創建比較表達式 i > 5  
var bin =   
Expression.GreaterThan(parameter, constant);  
   
// 獲取Lambda表達式  
var lambda =   
Expression.Lambda<Func<int, bool>>(bin, parameter);  
   
// 通過 Compile 方法獲取 Delegate  
var _r = ints.Where(lambda.Compile());

  

  動態構建C# Lambda表達式例子②

  1、准備例子

var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

  2、要實現的表達式 

var r = ints.Where(i => i > 5 && i <= 7); 

  3、動態創建該表達式具體代碼

// 創建參數 i  
var parameter =   
Expression.Parameter(typeof(int), "i");  
   
// 創建表達式 i > 5   
var con1 =   
Expression.Constant(5);  
var bin1 =   
Expression.GreaterThan(parameter, con1);  
   
// 創建表達式 i <= 7  
var con2 =   
Expression.Constant(7);  
var bin2 =   
Expression.LessThanOrEqual(parameter, con2);  
   
// 組合兩個表達式  
var body =   
Expression.And(bin1, bin2);  
   
// 獲取 Lambda 表達式  
var lambda =   
Expression.Lambda<Func<int, bool>>(body, parameter);  
   
var _r = ints.Where(lambda.Compile());  

  在例子②中,我們對復雜的表達式進行了分解,並使用 And 完成多個表達式的組裝,由此我們可以創建更加復雜的邏輯組合,比如例子③。

 

  動態構建C# Lambda表達式例子③

  1、准備例子

var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  

  2、要實現的表達式 

var r = ints.Where(i => (i > 5 && i <= 7) || (i == 3));

  3、動態創建該表達式具體代碼

// 創建參數 i  
var parameter =   
Expression.Parameter(typeof(int), "i");  
 
// 創建表達式 i > 5  
var con1 =   
Expression.Constant(5);  
var bin1 =   
Expression.GreaterThan(parameter, con1);  
 
// 創建表達式 i < 7  
var con2 =   
Expression.Constant(7);  
var bin2 =   
Expression.LessThanOrEqual(parameter, con2);  
 
// 創建表達式 i == 3  
var con3 =   
Expression.Constant(3);  
var bin3 =   
Expression.Equal(parameter, con3);  
 
// 組合 i > 5 && i <= 7  
var body =   
Expression.And(bin1, bin2);  
 
// 組合 ( i > 5 && i <= 7) OR (i == 3)  
body = Expression.Or(body, bin3);  
 
var lambda =   
Expression.Lambda<Func<int, bool>>  
(body, parameter);  
var _r = ints.Where(lambda.Compile());  

  

  動態構建C# Lambda表達式例子④

  1、准備例子

var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  

  2、要實現的表達式 

var r = ints.Select(i => i % 2 == 0 ? i : 0); 

  3、動態創建該表達式具體代碼

// 創建參數 i  
var parameter =   
Expression.Parameter(typeof(int), "i");  
 
// 創建表達式 i % 2  
var con1 =   
Expression.Constant(2);  
var bin1 =   
Expression.Modulo(parameter, con1);  
 
// 創建表達式 (i % 2) == 0  
var con2 =   
Expression.Constant(0);  
var bin2 =   
Expression.Equal(bin1, con2);  
 
// 創建表達式 IIF(((i % 2) = 0), i, 0)  
var bin3 =   
Expression.Condition  
(bin2, parameter, Expression.Constant(0));  
 
var lambda =   
Expression.Lambda<Func<int, int>>(bin3, parameter);  
var _r = ints.Select(lambda.Compile());

  

動態構建C# Lambda表達式例子⑤

  1、准備例子

var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };  

  2、要實現的表達式 

Array.ForEach<int>(ints, i => Console.WriteLine(i));

  3、動態創建該表達式具體代碼

// 創建參數i  
var parameter =   
Expression.Parameter(typeof(int), "i");  
 
// 獲取 Console.WriteLine MethodInfo  
MethodInfo method =   
typeof(Console).GetMethod(  
"WriteLine", new Type[] { typeof(int) });  
 
// 創建表達式   
var call = Expression.Call(method, parameter);  
 
var lambda =   
Expression.Lambda<Action<int>>(call, parameter);  
Array.ForEach<int>(  
ints, lambda.Compile());  

  

  是該花點時間去好好研究一下 System.Linq.Expressions Namespace 了……

  動態構建C# Lambda表達式的基本內容就向你介紹到這里,希望那個對你了解和掌握使用動態構建C# Lambda表達式有所幫助。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM