type TypeA () = class end
type TypeB () = inherit TypeA ()
// "The type 'TypeA' does not match the type 'TypeB'":
let iDict : IDictionary<TypeA, bool> = [ TypeB (), true; TypeB (), false ] |> dict
let d = Dictionary<TypeA, bool> ()
// This is OK, though:
d.Add (TypeB (), false)
为什么IDictionary键与派生类型不兼容?
答案 0 :(得分:2)
让我们看看两种方法之间的差异:
在第一种情况下,您正在创建一个列表:
[ 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
。