我刚遇到表达式树,我发现使用LINQ比使用Func<T, Boolean>
更好。但是,我发现我不能直接将Expression传递给LINQ方法,比方说Select
方法。但我发现有一个Compile
方法与Expression相关联,将其转换为普通Func
。现在我一直在想,是否正确地调用Expression(通过使用Compile方法),如果是这样,那么Func
和Expression
之间会有什么区别。如果它不是正确的方法那么如何使用它,例如通过这个:
Expression<Func<T, Bool>> Test
到
Data.Where(Test) --> Test can't be passed to it directly
答案 0 :(得分:6)
使用Expression
vs Func
实际上取决于您的使用案例以及您正在使用的Linq提供商。
如果您正在使用Entity Framework,Linq to SQL或任何其他查询提供程序将表达式树转换为其他查询语言,那么您 使用Expression
。
如果您使用Linq to Objects,那么您可以选择。通常,您希望直接使用Func
,而无需先创建表达式然后再编译它。
如果你正在做的事情需要在运行时构建任意和复杂的查询,可能使用Expression
。在这种情况下,您可以在执行查询之前调用compile
。通常的例子是用户通过UI提供复杂的搜索查询。
答案 1 :(得分:2)
基本上,表达式树是一种可以编译成可执行代码的数据结构。
有些方法要求您提供表达式树,因为它们需要分析表达式中的内容,以便基于此做出决策。此外,LINQ提供程序对SQL等数据源执行这些表达式,分析它们以将代码转换为特定的SQL方言。
在上面的例子中,表达式树永远不会被编译。
此外,你不想使用表达式树&#39;如果您未根据条件和用例构建可能的可执行代码,则可以解决任何问题。如果你只是声明表达式树,因为你觉得它们很强大,你就没有以正确的方式,因为你要增加额外的开销,将它们编译给代表以使它们可执行......
我还要补充说,表达式树非常强大,因为它实际上就像使用抽象语法树(AST)构建C#代码,而常规语言编译流程正在翻译人类编程语言,如将C#转换为AST,然后转换为中间语言或机器代码。换句话说,它就像拥有一个运行时编译器。
在早期的.NET中,这只能使用 reflection emit ,Mono Cecil或其他中间语言编织器,并想象一下如何使用.NET编写类似() => "hello world"
的内容。中间语言......!