关于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));
新闻热点
疑难解答