Давайте посмотрим на различия между двумя подходами:
В первом случае вы создаете список:
[ TypeB (), true; TypeB (), false ]
Это тип (TypeB * bool) list
.
dict имеет тип seq<'Key * 'Value> -> IDictionary<'Key,'Value> (requires equality)
.
Следовательно, применяя функцию dict
dict [ TypeB (), true; TypeB (), false ]
приводит к значению типа IDictionary<TypeB, bool>
.
IDictionary<TypeB, bool>
не эквивалентно IDictionary<TypeA, bool>
, это совершенно разные и несовместимые типы, отсюда и ошибка компилятора.
Если вы хотите таким образом инициализировать свой словарь из коллекции более производных типов, вам придется явно выполнить приведение вверх, например:
let iDict =
[ TypeB (), true; TypeB (), false ]
|> List.map (fun (a,b) -> (a :> TypeA), b)
|> dict
Во втором примере эта проблема не материализовалась, потому что вы изначально создали Dictionary<TypeA, bool>
.
Затем вы используете метод Add
, чтобы добавить что-нибудь из TypeB
в словарь. Поскольку Add
- это метод, F # может выполнять автоматическое преобразование аргумента с повышением, так что ваше значение TypeB
будет автоматически преобразовано в TypeA
.
person
TheInnerLight
schedule
17.07.2016
KeyValuePair<'Key, 'Value>
не ковариантен по'Key
? - person ildjarn   schedule 17.07.2016