在向大家详细介绍创建LINQ Expression tree节点之前,首先让大家了解下节点该如何创建,然后全面介绍。
创建LINQ Expression tree节点
当了解LINQ Expression tree的概念后,就可以来讨论一下这棵树里面的节点该如何创建。LINQ Expression tree节点一般是通过System.Linq.Expression.Expression这个类上的工厂方法来创建的。包括以下的一些方法:
- Add : BinaryExpression
- AddChecked : BinaryExpression
- And : BinaryExpression
- AndAlso : BinaryExpression
- ArrayIndex : BinaryExpression
- ArrayLength : UnaryExpression
- Call : MethodCallExpression
- Coalesce : BinaryExpression
- Condition : ConditionalExpression
- Constant : ConstantExpression
- Convert : UnaryExpression
- ConvertChecked : UnaryExpression
- Divide : BinaryExpression
- Equal : BinaryExpression
- ExclusiveOr : BinaryExpression
- Field : MemberExpression
- GreaterThan : BinaryExpression
- GreaterThanOrEqual : BinaryExpression
- Invoke : InvocationExpression
- Lambda : Expression<TDelegate>
- LeftShift : BinaryExpression
- LessThan : BinaryExpression
- LessThanOrEqual : BinaryExpression
- ListInit : ListInitExpression
- MakeBinary : BinaryExpression
- MakeMemberAccess : MemberExpression
- MakeUnary : UnaryExpression
- MemberInit : MemberInitExpression
- Modulo : BinaryExpression
- Multiply : BinaryExpression
- MultiplyChecked : BinaryExpression
- Negate : UnaryExpression
- NegateChecked : UnaryExpression
- New : NewExpression
- NewArrayBounds : NewArrayExpression
- NewArrayInit : NewArrayExpression
- Not : UnaryExpression
- NotEqual : BinaryExpression
- Or : BinaryExpression
- OrElse : BinaryExpression
- Parameter : ParameterExpression
- Power : BinaryExpression
- Property : MemberExpression
- PropertyOrField : MemberExpression
- Quote : UnaryExpression
- RightShift : BinaryExpression
- Subtract : BinaryExpression
- SubtractChecked : BinaryExpression
- TypeAs : UnaryExpression
- TypeIs : TypeBinaryExpression
- UnaryPlus : UnaryExpression
上述列表中每个名字其实对应着一组重载,参数不同,但返回值的类型是一样的。这些工厂方法所生成的表达式的意义应该说还是很直观的,就不特别介绍了。经常跟编译器打交道的话应该对这些名字尤其熟悉。
这些工厂方法对应的类的层次结构是:
- System.Object
- System.Linq.Expressions.Expression
- System.Linq.Expressions.BinaryExpression
- System.Linq.Expressions.ConditionalExpression
- System.Linq.Expressions.ConstantExpression
- System.Linq.Expressions.InvocationExpression
- System.Linq.Expressions.LambdaExpression
- System.Linq.Expressions.Expression<TDelegate>
- System.Linq.Expressions.MemberExpression
- System.Linq.Expressions.MethodCallExpression
- System.Linq.Expressions.NewExpression
- System.Linq.Expressions.NewArrayExpression
- System.Linq.Expressions.MemberInitExpression
- System.Linq.Expressions.ListInitExpression
- System.Linq.Expressions.ParameterExpression
- System.Linq.Expressions.TypeBinaryExpression
- System.Linq.Expressions.UnaryExpression
观察可得知,LINQ Expression tree节点中的类只能用于表现表达式,而无法表现“更大”的语法结构,例如赋值表达式、一般语句等。这是LINQ v1的一个重要限制,也是为什么C# 3.0的规范里明确提到一个能赋值给Expressin<TDelegate>类型的lambda表达式的方法体只能是一个表达式,而不能是一个代码块——代码块无法通过LINQ v1里的Expression tree表示。同时也值得注意的是,LINQ Expression tree本质上是一棵静态类型的树——所有节点所表示的类型都能够在编译时确定。
【编辑推荐】