for*_*i23 9 c# linq f# quotations
我可以Expr<'a -> 'b>通过以下代码段将类型的引用转换为Linq表达式:
/// Converts a F# Expression to a LINQ Lambda
let toLambda (exp:Expr) =
let linq = exp.ToLinqExpression() :?> MethodCallExpression
linq.Arguments.[0] :?> LambdaExpression
/// Converts a Lambda quotation into a Linq Lamba Expression with 1 parameter
let ToLinq (exp : Expr<'a -> 'b>) =
let lambda = toLambda exp
Expression.Lambda<Func<'a, 'b>>(lambda.Body, lambda.Parameters)
Run Code Online (Sandbox Code Playgroud)
现在我想转换类型的引用,Expr<'a * 'b -> 'c>甚至可能转换为类型Expr<'a -> 'b -> 'c>的Linq Lambda表达式Expression<Func<'a,'b'c>>.
我怎样才能做到这一点?
此致,forki
Tom*_*cek 13
我不确定这是否由F#PowerPack中提供的LINQ模块直接支持.但是,您可以实现自己对F#库生成的LINQ表达式的后处理,将其转换为通常形式的C#lambda函数:
以下函数采用LINQ表达式,该表达式构造为LambdaExpression单个参数的多个嵌套表达式(即F#转换器生成的结构),并返回最内层表达式的参数列表和主体:
let rec translateExpr (linq:Expression) =
match linq with
| :? MethodCallExpression as mc ->
let le = mc.Arguments.[0] :?> LambdaExpression
let args, body = translateExpr le.Body
le.Parameters.[0] :: args, body
| _ -> [], linq
Run Code Online (Sandbox Code Playgroud)
现在您可以使用它来获取Func类型的普通委托,int -> int -> int -> int如下所示:
let linq = (<@@ fun a b c -> (a + b) * c @@>).ToLinqExpression()
let args, body = translateExpr liq
let f = Expression.Lambda<Func<int, int, int, int>>
(body, args |> Array.ofSeq)
f.Compile().Invoke(10, 11, 2)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2631 次 |
| 最近记录: |