2011-04-07 104 views
0

我想基于包含元素(String,Int,Datetime等)的类型来处理字典的内容。以下是一个小测试片段,它载入一些测试数据,然后按类型进行提取。在数据类型上匹配时约束不匹配错误

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

错误信息

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

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

由于.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() 
+0

这里有很好的冗余 - 正如你指出我需要她的所有东西(类型信息等)都可以从网络对象本身获得。谢谢 – BrendanC 2011-04-07 18:37:56

2

甲.NET Type通过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"