演员/转换问题

时间:2011-04-12 23:03:09

标签: f# dictionary casting match tuples

在下面的代码片段中,我试图提取包含在嵌套元组中的recid,该元组形成一个dict键。 嵌套元组格式是(Int32,(boolean,boolean)) -

我正在寻找Int32项目的价值(即 实际上是db记录的行ID。

在下面的匹配代码中,我正在尝试将recid添加到列表中,但首先我将对象转换为整数。
但是,这会产生以下错误 - 不确定原因?

错误: 这种运行时强制或类型测试从类型'a到int32
涉及基于此程序点之前的信息的不确定类型。 某些类型不允许运行时类型测试。需要进一步的类型注释。 这里引用的字典定义为:

// Create Dict  
let rdict =  new Dictionary<_,_>()
// Add elements
rdict.Add( (x.["PatientID"],(true,true) ),ldiff) 

// Extract Dict items 
let reclist = new ResizeArray<int32>()
for KeyValue(k,v) in rdict do
match k with
    | ((recid,(true,true)) ->
     printfn "Found a matching Record: %A " recid;   // <- prints correct result
     let n = (recid:?> int32)                            // <- coercion error
         reclist.Add(n)

2 个答案:

答案 0 :(得分:1)

假设rdictDictionary<int*(bool*bool), _>然后生成ResizeArray<int>我建议:

let reclist =
    (ResizeArray<_>(), rdict.Keys)
    ||> Seq.fold(fun list (id,_) -> list.Add id; list)

另外,Dictionary<int*(bool*bool), _>让我感到奇怪。为什么不Dictionary<int*bool*bool, _>?即,为什么将bool对作为第二个元组嵌套?如果您进行此更改,则可以将rdict.Add称为:

rdict.Add ((x.["PatientID"], true, true), ldiff)

reclist代替:

let reclist =
    (ResizeArray<_>(), rdict.Keys)
    ||> Seq.fold(fun list (id,_,_) -> list.Add id; list)

编辑:在评论中,您提到了根据ResizeArray键中两个bool的不同组合构建单独的Dictionary的愿望。以下是关于这样做的一个想法:

let reclistOnlyA, reclistOnlyB, reclistBoth, reclistNeither =
    ((ResizeArray<_>(), ResizeArray<_>(), ResizeArray<_>(), ResizeArray<_>()), rdict.Keys)
    ||> Seq.fold(fun (a, b, both, neither as lists) (id, bools) ->
        (match bools with
         | true, false  -> a
         | false, true  -> b
         | true, true   -> both
         | false, false -> neither).Add id
        lists)

答案 1 :(得分:0)

为了完整性和未来的参考,我只想在进一步测试的基础上发布我的结果。 通过装箱/拆箱,我能够成功修改我之前发布的代码。

希望将来对其他人有用。

    // Add initial value note the box call here
diff_dict.Add( (box x.["PatientID"],(true,true) ),ldiff) 


let reclist = new ResizeArray<int32>()
for KeyValue(k,v) in rdict do
    //printfn "Difference Dictionary - Key: %A; Value: %A; " k v 
    match k with
        // extract the result - note the 'unbox' call
        | (recid,(true,false)) ->  let n:int32 = unbox recid
                                   reclist.Add(n)