我该怎么做才能使以下工作?
我需要创建一个接受 Expr 列表并返回 Expr (Expr list -> 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
@@>)
我创建了 DataObject 类型来添加 args 的值。但不知何故,我无法设法让代码迭代不同的 args (args.[0] .. args.[i])。我得到的信息是:
变量 'arg' 绑定在引号中,但用作拼接表达式的一部分。这是不允许的,因为它可能会超出其范围。
如果我显式访问 args (args.[0], args.[1], ...),则解决方案有效,但是一旦我尝试添加迭代,我就会遇到问题。因为 args 列表的长度是灵活的,所以这对我来说不是一个可行的解决方案。
我尝试了不同的方法,但没有成功。有什么解决办法吗?
[编辑]
在我的解决方案中添加 Tomas 的反馈给我带来了这个:
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 构造以获得正确的转换。有任何想法吗?