匹配数据类型时的约束不匹配错误

时间:2011-04-07 04:03:38

标签: f# dictionary types match

我正在尝试根据所包含元素的类型(String,Int,Datetime等)处理字典的内容。以下是一个小测试片段,它加载一些测试数据,然后按类型提取。

然而,我得到以下约束不匹配错误,我不明白 - 任何想法?

错误信息

  

unmapdict.fsx(29,23):错误FS0193:类型约束不匹配。   
“String”类型与“Type”类型

不兼容
open System
open System.Collections.Generic

// Type for dict entries
type dStruct =  {
   ftype: Type; 
   fvalue:obj;
}

let main() =
    printfn "\n>>>>>> Extract Dictionary Elements  <<<<< \n" 
    let ddict = new Dictionary<string, dStruct>()
    let str = "String Data"
    let rstring =  { ftype=str.GetType(); fvalue=str ;}
    ddict.Add("String", rstring)
    let intn = 999
    let rint32 =  { ftype=intn.GetType(); fvalue=intn ;}
    ddict.Add("Int32", rint32)

    let rdatetime =  {ftype=System.DateTime.Now.GetType(); fvalue=System.DateTime.Now}
    ddict.Add("DateTime", rdatetime)

    // Extract dict value elements; emumerate data types
    ddict
        |> Seq.map ( fun (KeyValue(k,v)) -> v)
        |> Seq.iter (fun v ->  
                    // Error occurs here >>
                    match v.ftype with 
                    | :?System.String -> printfn "String Found ";
                    | :?System.Int32 -> printfn "Integer Found ";
                    | :?System.DateTime -> printfn "DateTime Found ";
                    |_ -> printfn "Unmatched Element"
                    // printfn "Dict: ftype: %A; fvalue: %A" v.ftype v.fvalue
                    )

    printfn "\n>>>>>> F# Done  <<<<< \n" 

main()

2 个答案:

答案 0 :(得分:2)

Type返回的.NET GetType与类不同。相反,它是类Type的一个实例。此外,Type不能用于模式匹配(除非我们定义特殊的活动模式),但我们可以比较相等性。

如果您更改这样的代码,它将起作用:

               if v.ftype  = typeof<String> then printfn "String Found "
               elif v.ftype = typeof<System.Int32> then printfn "Integer Found "
               elif v.ftype = typeof<System.DateTime> then printfn "DateTime Found "
               else printfn "Unmatched Element"

答案 1 :(得分:2)

由于.NET对象带有它们的类型,我没有看到dStruct类型的任何指向(无论如何都是误导性的,因为它不是结构体)。在相关的说明中,您的类型测试模式(:? string等)不起作用,因为您正在测试类Type的实例,当您应该测试实际的实例时关心。那就是:

let main() =
    printfn "\n>>>>>> Extract Dictionary Elements  <<<<< \n" 
    let ddict = new Dictionary<string, obj>()
    let str = "String Data"
    ddict.Add("String", str)
    let intn = 999
    ddict.Add("Int32", intn)

    ddict.Add("DateTime", System.DateTime.Now)

    // Extract dict value elements; emumerate data types
    ddict
        |> Seq.map ( fun (KeyValue(k,v)) -> v)
        |> Seq.iter (fun v ->  
                    match v with 
                    | :?System.String as s -> printfn "String Found: %s" s;
                    | :?System.Int32 as i -> printfn "Integer Found: %i" i;
                    | :?System.DateTime as dt -> printfn "DateTime Found: %A" dt;
                    |_ -> printfn "Unmatched Element"
                    )

    printfn "\n>>>>>> F# Done  <<<<< \n" 

main()