C# 泛型 (Generics)編譯機制
第一輪編譯時,編譯器隻為Stack<T>(棧算法)類型産生“泛型版”的IL代碼與中繼資料-----并不進行泛型類型的執行個體化,T在中間隻充當占位符
JIT編譯時,當JIT編譯器第一次遇到Stack<int>時,将用int替換“泛型版”IL代碼與中繼資料中的T---進行泛型類型的執行個體化。
CLR為所有類型參數為“引用類型”的泛型類型産生同一份代碼;但如果類型參數為“值類型”,對每一個不同的“值類型”,CLR将為其産生一份獨立的代碼
C# 泛型 (Generics)特點
1、如果執行個體化泛型類型的參數相同,那麼JIT編譯器會重複使用該類型,是以C#的動态泛型能力避免了C++靜态模闆可能導緻的代碼膨脹的問題。
2 、C#泛型類型攜帶有豐富的中繼資料,是以C#的泛型類型可以應用于強大的反射技術。
3、C#的泛型采用“基類,接口,構造器,值類型/引用類型”的限制方式來實作對類型能數的“顯式限制”,提高了類型安全的同時,也喪失了C++模闆基于“簽名”的隐式限制所具有的高靈活性
Lambda 表達式
Lambda 表達式是一種可用于建立委托或表達式目錄樹類型的匿名函數。 通過使用 lambda 表達式,可以寫入可作為參數傳遞或作為函數調用值傳回的本地函數。 Lambda 表達式對于編寫 LINQ 查詢表達式特别有用。若要建立 Lambda 表達式,需要在 Lambda 運算符 => 左側指定輸入參數(如果有),然後在另一側輸入表達式或語句塊。 例如,lambda 表達式 x => x * x 指定名為 x 的參數并傳回 x 的平方值。
例子:
用表達式樹轉換以下Lamda表達式
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());