这是可以在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/

10-13 01:12