UnaryExpression所思
按照msdn的解释,UnaryExpression的意思是:表示包含一元运算符的表达式(一元:说明了只有一个操作数,通过Operand属性成员即可获得其操作数)。
UnaryExpression的NodeType有:
ArrayLength/Convert/ConvertChecked/Negate/NegateChecked/Not/Quote/TypeAs/UnaryPlus
这里重点说ExpressionType枚举成员:Quote,也就是说,我们利用Expression.Quote方法生成的表达式既是UnaryExpression。这个方法在msdn中的解释是:创建一个表示具有类型 Expression 的常量值的表达式的 UnaryExpression。这个解释真的有点不好懂,还是直接利用Expression.Quote创建一个UnaryExpression好了:
UnaryExpression unaryExpression = Expression.Quote(Expression.Constant(10));
运行,产生错误:Quoted expression must be a lambda
这里得出一个结论,Expression.Quote(Expression expression)方法中的参数要么是LambdaExpression要么是Expression<TDelegate>(其中后者继承自前者)。
UnaryExpression也许是个经常用到的表达式,我们在分析IQueryable<T>的扩展方法所得到的表达式时经常会用到该表达式,例如:
var names = new[] { "Zhang Liang", "Jiang Chuan", "Hua Dong", "You min" };
var query = names.AsQueryable<String>().Where(s => s.Length > 10);
其实,这里面的s=>s.Length>10这个LambdaExpression表达式其实就是被封装在UnaryExpression表达式中,作为Where方法的一个参数而已:
String[] names = new[] { "Zhang Liang", "Jiang Chuan", "Hua Dong", "You min" };
IQueryable<String> query = names.AsQueryable<String>().Where(s => s.Length > 10);
MethodCallExpression methodCallExpression = query.Expression as MethodCallExpression;
Console.WriteLine(methodCallExpression.Arguments[1].NodeType);
//得到ExpressionType.Quote
UnaryExpression unaryExpression = methodCallExpression.Arguments[1] as UnaryExpression;
Console.WriteLine(unaryExpression.Operand.NodeType);
//得到ExpressionType.Lambda
因此,我们在分析IQueryable<T>的扩展方法(如上面的Where)时,切忌不可认为Where的第二个参数在表达式目录树中是一个LambdaExpression类型(或者其子类型)的节点。