我正在尝试根据所包含元素的类型(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()
答案 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()