Ошибка несоответствия ограничения при сопоставлении с типом данных - PullRequest
0 голосов
/ 07 апреля 2011

Я пытаюсь обработать содержимое словаря на основе типа содержащегося элемента (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 ]

2 голосов
/ 07 апреля 2011

Поскольку объекты .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()
2 голосов
/ 07 апреля 2011

.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"
...