轉載:http://www.educity.cn/develop/1407905.html,並整理!html
對於C# Lambda的理解咱們在以前的文章中已經講述過了,那麼做爲Delegate的進化使用,爲了讓代碼簡潔和優雅的呈現,C# Lambda表達式的使用功不可滅,那麼依託外部條件如何動態構建C# Lambda表達式呢。下面讓咱們來具體的看看實施。數據庫
或許你會奇怪這個需求是如何產生的…… 首先,Lambda 在 DLinq 中承擔了以往 T-SQL 的部分角色;其次,在數據庫設計中,咱們每每須要依據外部未知的動態條件組合來查詢數據。而問題在於做爲一種靜態語言,咱們顯然沒法用動態語法或者拼接字符串的方法來建立一個Delegate/Lambda,那麼如何達到相似的目的呢?CodeDom?Emit?或許最佳的選擇是 System.Linq.Expressions.Expression。數據庫設計
i => i > 5
在這個表達式中,"i" 被稱爲 Parameter,"i > 5" 是 Body。咱們能夠對 Body 進行更進一步的分解,那麼 "i > 5" 分別包含參數(i)、操做符(>)以及一個常數(5)。全部這些經過特定順序的組合,從而構建一個完整的 Lambda 表達式。學習
一、準備例子spa
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
二、要實現的表達式 設計
var r = ints.Where(i => i > 5);
三、動態建立該表達式具體代碼htm
// 建立參數 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());
一、準備例子blog
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
二、要實現的表達式 ci
var r = ints.Where(i => i > 5 && i <= 7);
三、動態建立該表達式具體代碼字符串
// 建立參數 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 完成多個表達式的組裝,由此咱們能夠建立更加複雜的邏輯組合,好比例子③。
一、準備例子
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
二、要實現的表達式
var r = ints.Where(i => (i > 5 && i <= 7) || (i == 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());
一、準備例子
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
二、要實現的表達式
var r = ints.Select(i => i % 2 == 0 ? i : 0);
三、動態建立該表達式具體代碼
// 建立參數 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());
一、準備例子
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
二、要實現的表達式
Array.ForEach<int>(ints, i => Console.WriteLine(i));
三、動態建立該表達式具體代碼
// 建立參數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表達式有所幫助。