關于IEnumerable和IQueryable的區別,這事還要從泛型委托Func<T>說起。來看一個簡單的泛型委托例子:
class Program{static void Main(string[] args){Func<int, bool> f = i => i > 5;Console.WriteLine(f(3));Console.WriteLine(f(10));Console.ReadKey();}}
Func<T>是"語法糖",實際上,編譯器在內部會生成一個臨時方法,再執行該方法。等同于如下:
class Program{static void Main(string[] args){Func<int, bool> f = DoSth;Console.WriteLine(f(3));Console.ReadKey();}static bool DoSth(int i){return i > 5;}}
以上,.NET內部運作的路徑是:編寫C#代碼→編譯器編譯成中間語言IL→運行時JIT編譯成本地語言執行
■ 使用表達式樹 Expression Tree
可是,有時候我們希望在運行時執行代碼,該怎么辦呢?
.NET為我們提供了Expression Tree,允許我們在運行時執行代碼。
比如以上Func<int, bool> f = i => i > 5;這個表達式,Expression Tree這樣理解這個表達式:
○ f是Expression<Func<int, bool>>類型,級Expression<TDelegate>類型○ =>被理解成BinaryExpression類型○ =>左右兩邊的i被理解成ParameterExpression○ =>右邊的5被理解成ConstantExpression
于是,如果我們用Expression Tree,在運行時執行代碼,可以按如下寫:
class Program{static void Main(string[] args){//Func<int, bool> f = i => i > 5;ParameterExpression iparam = Expression.Parameter(typeof (int), "i");ConstantExpression constExp = Expression.Constant(5, typeof (int));BinaryExpression greaterThan = Expression.GreaterThan(iParam, constExp);Expression<Func<int, bool>> f = Expression.Lambda<Func<int, bool>>(greaterThan, iParam);Func<int, bool> myDele = f.Compile();Console.WriteLine(myDele(3));
新聞熱點
疑難解答