MSDN文档称:
Expression.Quote
方法创建一个表示类型为Expression的常量值的表达式的UnaryExpression。
我已经成功地使用Expression类手动构建用于LINQ查询中的谓词表达式,但从未遇到需要使用Expression.Quote的情况。
什么时候以及为什么要使用它?从我看到带有它们的LINQ表达式来看,它们似乎只是在不添加任何价值的情况下包装现有表达式。
引用(Quote)方法/节点的目的是什么?
MSDN文档称:
Expression.Quote
方法创建一个表示类型为Expression的常量值的表达式的UnaryExpression。
我已经成功地使用Expression类手动构建用于LINQ查询中的谓词表达式,但从未遇到需要使用Expression.Quote的情况。
什么时候以及为什么要使用它?从我看到带有它们的LINQ表达式来看,它们似乎只是在不添加任何价值的情况下包装现有表达式。
引用(Quote)方法/节点的目的是什么?
Expression.Quote
指定一个lambda表达式应该被视为一个表达式树而不是函数,并且它在其操作数上引入了闭包语义。
当您使用Expression.Call
构建MethodCallExpression
时,任何作为lambda表达式(LambdaExpression
/Expression<TDelegate>
)的参数必须在传递之前使用Expression.Quote
进行包装。
所以对于类型为Expression<Func<bool>>
的参数,当您创建如下实例时:() => true
,表达式的Type
属性将是Func<bool>
,而表达式的类型(调用GetType
)将是Expression<Func<bool>>
。
因此,要获取具有正确Type
属性值的Expression
,请将lambda表达式传递到Expression.Quote
中,并将其作为参数传递给Expression.Call
。
我通过反射查看了Expression.Quote
,虽然唯一的参数类型是Expression
,但它必须派生自LambdaExpression
,并且在方法内部进行了检查。出于兴趣,有没有人知道为什么MS不直接使参数类型为LambdaExpression
?
正如StevenH所指出的那样,Expression.Quote
用于实现LINQ查询提供程序。 Queryable
上的所有接受lambda表达式的方法(例如Where
、OrderBy
、GroupBy
等)在内部使用Expression.Call
构造MethodCallExpression
并使用Expression.Quote
调用包装lambda表达式参数。
有关Expression.Quote
的更详细解释,请阅读这个答案。
Func<>
,那么这就是你所需要的全部。但对于许多LINQIQueryable<T>
扩展方法而言,参数类型实际上是Expression<Func<>>
,在这种情况下,你将需要使用Expression.Quote
。我还没有尝试在.NET 4.5中进行这个操作,但我认为它应该是一样的。在写作时,我可能正在使用.NET 3.5。 - John Mills