c# - 如何使用 F# lambda 创建 Linq 表达式树?

标签 c# linq f# expression-trees

这是可以在 C# 中完成的操作 -

var two = 2;
System.Linq.Expressions.Expression<System.Func<int, int>> expr = x => x * two;
expr.Compile().Invoke(4); // returns 8

我希望在 F# 中做同样的事情。这是我尝试过的,但没有编译 -

let two = 2
let expr = (fun x -> x * two) : System.Linq.Expressions.Expression<System.Func<int, int>>
expr.Compile().Invoke(4) // desired to return 8

也许可以预见,第 2 行编译失败并出现以下错误 -

"This function takes too many arguments, or is used in a context where a function is not expected."
let expr = (fun x -> x * two) : System.Linq.Expressions.Expression<System.Func<int, int>>
            ^^^^^^^^^^^^^^^^

最佳答案

我不确定您为什么要避免使用 F# 引号 - 在表面上,它们与 C# 表达式树几乎相同,如果您想在 F# 中创建表达式树,编译器将使用引号无论如何都在掩护下......

无论如何,您可以在不显式写出 <@ .. @> 的情况下执行此操作因为当函数作为参数传递给方法时,编译器可以自动引用函数。所以你可以这样做:

type Expr = 
  static member Quote(e:Expression<System.Func<int, int>>) = e

let two = 2
let expr = Expr.Quote(fun x -> x * two) 
expr.Compile().Invoke(4) // desired to return 8

编辑:但是,这实际上编译为一个 F# 引号,包裹在一个将其转换为 C# 表达式树的调用中。所以,最后,你会得到和你写的一样的东西:

open Microsoft.FSharp.Linq.RuntimeHelpers

let two = 2
let expr = 
  <@ System.Func<_, _>(fun x -> x * two) @>
  |> LeafExpressionConverter.QuotationToExpression 
  |> unbox<Expression<Func<int, int>>>
expr.Compile().Invoke(4) // desired to return 8

关于c# - 如何使用 F# lambda 创建 Linq 表达式树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23146473/

相关文章:

c# - 如何在 Windows 应用程序中使用 SMTP 服务器向手机发送短信?

c# - linq groupby 问题

c# - 检查列表中的下一个最高/最低值并选择该项目

f# - 无法从 FSharp.Data 实例化任何 F# 类型提供程序

.net - 在 F# 中组合异步计算

c# - 覆盖 WinForms 中的事件处理程序

c# - CultureInfo 和 ISO 639-3

c# - 计算2个数组有多少位置包含相等的元素

c# - 带有 IEnumerable<T> 键的 LINQ OrderBy

f# - 如何使用 Deedle 获取某个键及以下键的每一行?