次の作業を行うにはどうすればよいですか?
Expr リストを受け取り、Expr を返す関数を作成する必要があります (Expr リスト -> Epxr)。
type DataObject() =
let data = System.Collections.Generic.Dictionary<int, obj>()
member this.AddValue propertyIndex value = data.Add(propertyIndex, value)
member this.GetValue propertyIndex =
match data.TryGetValue propertyIndex with
| (true, value) -> value
| (false, _) -> box "property not found"
...
(fun args ->
<@@
let data = new DataObject(values)
args |> List.iteri (fun i arg -> data.AddValue i <@@ (%%arg) : string @@>)
data
@@>)
args の値を追加するために DataObject 型を作成しました。私が受け取るメッセージは次のとおりです。
変数 'arg' は引用符で囲まれていますが、結合された式の一部として使用されています。これは、その範囲を逸脱する可能性があるため、許可されていません。
引数に明示的にアクセスすると (args.[0]、args.[1]、...)、解決策は機能しますが、繰り返しを追加しようとするとすぐに問題が発生します。args のリストは長さが柔軟であるため、これは実行可能な解決策ではありません。
さまざまなアプローチを試みましたが、うまくいきませんでした。何か解決策はありますか?
[編集]
私のソリューションにトーマスのフィードバックを追加すると、次のようになります。
type DataObject(values: obj []) =
let propertyMap = new Map<int, obj>(values |> Seq.mapi (fun i value -> (i, value)))
member this.GetValue propertyIndex : obj =
match propertyMap.TryFind propertyIndex with
| Some(value) -> value
| None -> box "property not found"
(fun args ->
let boxedArgs =
args |> List.map (fun arg ->
match arg with
| Quotations.Patterns.Var var ->
if var.Type = typeof<int> then
<@@ (box (%%arg: int)) @@>
else if var.Type = typeof<string> then
<@@ (box (%%arg: string)) @@>
else if var.Type = typeof<System.Guid> then
<@@ (box (%%arg: System.Guid)) @@>
else
failwith ("Aha: " + var.Type.ToString())
| _ -> failwith ("Unknown Expr as parameter"))
<@@ new DataObject(%%(Expr.NewArray(typeof<obj>, boxedArgs))) @@>))
そして、これはうまくいきます!唯一のことは、正しい変換を得るために if ... else 構造を取り除きたいということです。何か案は?