Konvertieren von Ausdruck <'a ->' b> in Ausdruck <Func <'a, obj >>
Ich verwende F # 3.0 mit .NET 4.5 Beta und versuche, ein F # -Zitat des Typs zu konvertierenExpr<'a -> 'b>
zu einem LINQExpression<Func<'a, 'b>>
.
Ich habe mehrere Fragen gefunden, die Lösungen für dieses Problem bieten, aber diese Techniken scheinen nicht mehr zu funktionieren, vermutlich aufgrund von Änderungen in F # 3.0 oder .NET 4.5.
Konvertieren von F # -Zitaten in LINQ-AusdrückeExpression<Func<T, bool>>
von einer F # funcIn beiden Fällen löst die folgende Aktion eine Ausnahme aus, wenn ich den Code aus den Lösungen der beiden Fragen ausführe:
mc.Arguments.[0] :?> LambdaExpression
...wohermc
ist einMethodCallExpression
. Die Ausnahme ist:
System.InvalidCastException: Objekt vom Typ 'System.Linq.Expressions.MethodCallExpressionN' kann nicht in 'System.Linq.Expressions.LambdaExpression' umgewandelt werden.
Nein, das zusätzliche "N" am Ende vonMethodCallExpressionN
ist kein Tippfehler. Hat jemand einen Vorschlag? Vielen Dank.
AKTUALISIEREN
Hier ist eine vollständige Reproduktion. Es stellt sich heraus, dass dieser Code für einen Ausdruck wie gut funktioniert<@ fun x -> x + 1 @>
. Mein Problem ist, dass ich in meinem Fall eine konvertieren mussExpr<'a -> 'b>
inExpr<'a -> obj>
damit ich nicht alle meine lambda ausdrücke mit verunreinigen mussbox
. Ich habe dazu den ursprünglichen Ausdruck in diesen gespleißt:<@ %exp >> box @>
. Dies erzeugt ein Objekt mit dem richtigen Typ, aber dem Code, in den konvertiert werden sollExpression<Func<'a, obj>>
funktioniert nicht mehr.
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