Expr<'a -> 'b>
.NET 4.5ベータ版でF#3.0を使用しており、タイプのF#引用符をLINQに変換しようとしていExpression<Func<'a, 'b>>
ます。
この問題の解決策があるいくつかの質問を見つけましたが、おそらくF#3.0または.NET 4.5のいずれかが変更されたため、これらの手法は機能しなくなったようです。
どちらの場合も、どちらかの質問の解決策からコードを実行すると、次のアクションで例外がスローされます。
mc.Arguments.[0] :?> LambdaExpression
...どこにmc
ありますかMethodCallExpression
。例外は次のとおりです。
System.InvalidCastException:タイプ'System.Linq.Expressions.MethodCallExpressionN'のオブジェクトをタイプ'System.Linq.Expressions.LambdaExpression'にキャストできません。
いいえ、末尾の余分な「N」はMethodCallExpressionN
タイプミスではありません。誰か提案がありますか?ありがとう。
アップデート
これが完全な複製です。このコードは、のような式で正常に機能することがわかりました<@ fun x -> x + 1 @>
。私の問題は、私の場合、すべてのラムダ式に。を使用する必要がないように、にExpr<'a -> 'b>
変換する必要があることです。これは、元の式を次の式につなぎ合わせることによって行いました。これにより、正しいタイプのオブジェクトが生成されますが、変換するコードは機能しなくなります。Expr<'a -> obj>
box
<@ %exp >> box @>
Expression<Func<'a, obj>>
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