estoy usando C# .NET 3.0 con 4.5 beta, y estoy tratando de convertir un F # cotización del tipo Expr<'a -> 'b>
a un LINQ Expression<Func<'a, 'b>>
.Cómo convertir Expr <'a -> 'b> para la expresión <Func <'a, obj>>
He encontrado varias preguntas que tienen soluciones para este problema, pero esas técnicas ya no parecen funcionar, presumiblemente debido a cambios en F # 3.0 o .NET 4.5.
En ambos casos, cuando corro el código de las soluciones de cualquiera de estas preguntas, la siguiente acción se produce una excepción:
mc.Arguments.[0] :?> LambdaExpression
... donde mc
es un MethodCallExpression
. La excepción es:
System.InvalidCastException: No se puede convertir objeto de tipo 'System.Linq.Expressions.MethodCallExpressionN' al tipo 'System.Linq.Expressions.LambdaExpression'.
No, la "N" adicional al final de MethodCallExpressionN
no es un error tipográfico. alguien tiene una sugerencia? Gracias.
ACTUALIZACIÓN
Aquí es una reproducción completa. Resulta que este código funciona bien en una expresión como <@ fun x -> x + 1 @>
. Mi problema es que en mi caso necesito convertir un Expr<'a -> 'b>
en Expr<'a -> obj>
para que no tenga que ensuciar todas mis expresiones lambda con box
. Lo hice empalmando la expresión original en este: <@ %exp >> box @>
. Esto produce un objeto con el tipo correcto, pero el código para convertir a Expression<Func<'a, obj>>
ya no funciona.
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
Quizás esté siendo castigado por el uso de estilo sin puntos. ¿Qué sucede si utiliza '<@ fun x ->% exp x |> box @>' en su lugar? Cuando utilizas un estilo sin puntos, la expresión que estás convirtiendo no es una lambda, es una aplicación. – kvb
@kvb - Es una buena idea, pero cuando uso esa construcción, subraya '% exp' y me dice" Este valor no es una función y no se puede aplicar "y se niega a compilar. –
Sin embargo, '<@ fun x -> x |>% exp |> box @>' se compila. Lamentablemente, obtiene el mismo error cuando intento convertirlo. –