Como converter Expr <'a ->' b> para expressão <Func <'a, obj >>
Estou usando o F # 3.0 com o .NET 4.5 beta e estou tentando converter uma cotação F # do tipoExpr<'a -> 'b>
para um LINQExpression<Func<'a, 'b>>
.
Eu encontrei várias perguntas que têm soluções para esse problema, mas essas técnicas não parecem funcionar por mais tempo, presumivelmente devido a alterações no F # 3.0 ou no .NET 4.5.
Convertendo citações F # em expressões LINQExpression<Func<T, bool>>
de uma func de F #Em ambos os casos, quando executo o código das soluções de qualquer uma das perguntas, a seguinte ação lança uma exceção:
mc.Arguments.[0] :?> LambdaExpression
...Ondemc
é umMethodCallExpression
. A exceção é:
System.InvalidCastException: não é possível converter objeto do tipo 'System.Linq.Expressions.MethodCallExpressionN' para digitar 'System.Linq.Expressions.LambdaExpression'.
Não, o "N" extra no final deMethodCallExpressionN
não é um erro de digitação. Alguém tem uma sugestão? Obrigado.
ATUALIZAR
Aqui está uma reprodução completa. Acontece que esse código funciona bem em uma expressão como<@ fun x -> x + 1 @>
. Meu problema é que no meu caso eu preciso converter umExpr<'a -> 'b>
para dentroExpr<'a -> obj>
de modo que eu não tenho que colocar todas as minhas expressões lambda combox
. Eu fiz isso juntando a expressão original a esta:<@ %exp >> box @>
. Isso produz um objeto com o tipo correto, mas o código para converter paraExpression<Func<'a, obj>>
não funciona mais.
module Expr =
open System
open System.Linq.Expressions
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Linq.QuotationEvaluation
let rec private 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
let ToFuncExpression (expr:Expr<'a -> 'b>) =
let args, body = expr.ToLinqExpression() |> translateExpr
Expression.Lambda<Func<'a, 'b>>(body, Array.ofList args)
let exp = <@ fun x -> x + 1 @>
let r = Expr.ToFuncExpression <@ %exp >> box @>
printfn "%A" r