这个星期我一直在玩表达式树,我想知道为什么这个表达式在运行时会产生错误。
var pe = Expression.Parameter(typeof(Nullable<DateTime>));
var ex = Expression.Lambda<Func<DateTime?, bool>>(
(Expression<Func<DateTime?, bool>>) (x => x.HasValue), pe);这背后的想法是用表达式树api和linq表达式混合编写表达式树。它将使事情更容易编写,例如,而不是调用Expression.Property(...,..),我只需要x => x.Prop,对吗?
在我的示例中,而不是这个Expression.Property(..hasvalue..),我将使用以下内容:x.HasValue。这样可以节省我写作的时间,而且看起来更短,对吧?
问题是,这可能吗?
我想我可能错过了一些关于
Expression<Func<DateTime?, bool>> foo = x => x.HasValue (this works)和
Func<DateTime?, bool> bar = x => x.HasValue (this works too)那两个人背后到底发生了什么?是一样的吗?
linq表达式能与标准表达式树api混合吗?
请告诉我这件事,我感到迷茫。:)
发布于 2013-11-12 14:59:42
这是个好问题。你的两份报价
Expression<Func<DateTime?, bool>> foo = x => x.HasValue和
Func<DateTime?, bool> bar = x => x.HasValue这些都是同象性的例子:相同的符号(在您的例子中是x => x.HasValue)代表两个非常不同的对象。在第一种情况下,它表示表达式树;在第二种情况下,表示函数。前者可以被编译成后者,但它们是不同的类型,有不同的目的。在您的情况下,是声明告诉编译器要使用哪个版本。在没有这种上下文的情况下,编译器无法读取您的想法,而是决定退出。这就是为什么它不能编译:
var bat = x => x.HasValue;这就是为什么你的声明不能编译。
同象似性使IQueryable和IEnumerable看起来如此相似。当你调用
var filteredCollection = myCollection.Where(e => e.IsActive);实际上,您调用的方法具有不同的签名,具体取决于filteredCollection的类型( IEnumerable是Func<MyClass, bool>,IQueryable是Expression<Func<MyClass, bool>> )。
关于您的特定情况,您不能直接实现您想要做的事情,但是如果您编写了一个鬼鬼祟祟的扩展方法:
public static class ExpressionExtensions
{
public static Expression<Func<T, TProperty>> Lambda<T, TProperty>(this ParameterExpression pe, Expression<Func<T, TProperty>> property)
{
return Expression.Lambda<Func<T, TProperty>>(property, pe);
}
}然后你就可以这样做:
var pe = Expression.Parameter(typeof(DateTime?));
var ex = pe.Lambda<DateTime?, bool>(x => x.HasValue);https://stackoverflow.com/questions/19930389
复制相似问题