首先,表达式的类型自己并不是委托类型,但它能够经过多种方式隐式或者显式地转换成一个委托实例。匿名函数这个术语同时涵盖了匿名方法和Lambda,不少状况下二者可使用相互转换原则。express
Func<string, int> returnlength = delegate(string text) { return text.Length; };
Func<string, int> returnlength = (string text) => { return text.Length; };
Func<string, int> returnlength = (string text) => text.Length;
Func<string, int> returnlength = (text) => text.Length;
一: 表达式树函数
1.1基本知识性能
表达式树提供了一种抽象的方式将一些代码表示成一个对象树,表达式树主要用于LINQ,树中的每一个节点自己都是一个表达式。spa
不一样的表达式类型表明能在代码中执行的不一样操做:二元操做,一元操做,方法调用,构造函数调用等等。code
System.Linq.Expressions命名空间包含了表明表达式的各个类,它们都继承自Expression,一个抽象的主要包含一些静态工厂方法的类,这些方法用于建立其余表达式类的实例,然而,Expression类也包括两个属性。对象
1.Type属性表明表达式求值后的.NET类型,可把它视为一个返回类型。例如一个表达式要获取一个字符串的Length属性,该表达式的类型就是int。blog
2.NodeType属性返回所表明的表达式的种类。它是ExpressionType枚举的成员,包括LessThan、Multiply和Invoke等。仍然使用上面的例子,对于myString.Length这个属性访问来讲,其节点类型是MemberAccess。。继承
而且该属性能区分由相同的类表示的不一样种类的表达式。ip
示例以下:字符串
Expression first = Expression.Constant(2); Expression second = Expression.Constant(3); Expression add = Expression.Add(first, second);
Func<int> acmpiled = Expression.Lambda<Func<int>>(add).Compile(); //编译成可执行的委托方法。
Debug.Write(add);
该代码会产生输出“(2+3)”,这意味着这些表达式树类覆盖了ToString来产生可读的输出。
注意:“叶”表达式在代码中是最早建立的,咱们须要自上而下构建这些表达式。
1.2表达式树与委托
LambdaExpression是从Expression派生的类型之一,泛型类 Expression<TDelegate>又是从LambdaExpression派生的。Expression与 Expression<TDelegate>的区别在于:泛型类以静态类型的方法标识了它是什么种类的表达式,也就是说,他肯定了返回类型和参数。因此显然,TDelegate必须是一个委托类型。
注意:并不是全部的Lambda表达式都能转换成表达式树。不能将带有一个语句块(即便只有一个return语句)的Lambda转换成表达式树,只有对单个表达式进行求值的lambda才能够。表达式中不能包含赋值操做,由于在表达式中表示不了这种操做。
示例二以下:
Expression<Func<string, string, bool>> expression = (x, y) => x.StartsWith(y); Func<string, string, bool> complied = expression.Compile(); Debug.Write(complied("first", "second")); Debug.Write(complied("first", "fir"));
示例二等同于以下代码:
//构造调用方法的各个组件 MethodInfo method = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); //方法 ParameterExpression target= Expression.Parameter(typeof(string), "x"); //方法主 var methodArg = Expression.Parameter(typeof(string), "y"); //参数 Expression[] methodArgs = new [] { methodArg }; //参数列表 MethodCallExpression call = Expression.Call(target, method, methodArgs); //从以上组件建立CallExpression //将call转换为lambda表达式 ParameterExpression[] lambdaParameters = new[] { target, methodArg }; //参数 var lambda = Expression.Lambda<Func<string, string, bool>>(call, lambdaParameters); Func<string, string, bool> complied = lambda.Compile(); Debug.Write(complied("first", "second")); Debug.Write(complied("first", "fir"));