带有linq表达式的表达式树

时间:2013-11-12 13:23:39

标签: c# linq

本周我一直在玩表达树,我想知道为什么这个表达式在运行时会产生错误。

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 ???

混合使用

请赐教这个,我感到迷茫。 :)

1 个答案:

答案 0 :(得分:1)

这是一个很好的问题。你的两个引文

Expression<Func<DateTime?, bool>> foo = x => x.HasValue

Func<DateTime?, bool> bar = x => x.HasValue

homoiconicity 的示例:相同的符号(在您的情况下为x =&gt; x.HasValue)代表两个非常不同的对象。在第一种情况下,它表示表达式树;在第二个,一个功能。前者可以编译成后者,但它们是具有不同目的的不同类型。在您的情况下,声明告诉编译器要使用哪个版本。如果没有这种情况,编译器就无法读懂你的想法,而是决定纾困。这就是为什么这不会编译:

var bat = x => x.HasValue;

这就是为什么你的陈述不会编译。

同质性是使IQueryableIEnumerable看起来如此相似的原因。当你调用

var filteredCollection = myCollection.Where(e => e.IsActive);

您实际上是根据filteredCollection的类型调用具有不同签名的方法(Func<MyClass, bool>的{​​{1}}和IEnumerable的{​​{1}}。< / p>

关于你的具体情况,你无法直接达到你想要做的,但如果你写了一个偷偷摸摸的扩展方法:

Expression<Func<MyClass, bool>>

然后你可以这样做:

IQueryable