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