假设我定义了以下接口和实现它的类:
type IGreeter =
abstract member GetGreeting: unit -> string
type Human =
interface IGreeter with
member this.GetGreeting () = "Why hello there"
大。并说我在某个地方list<Human>
。现在,问题是,如何将其转换为list<IGreetable>
?例如:
let humans: Human list = ...
let greeters: IGreeter = (upcast humans)
这会发出警告和错误:
Warning FS0059: The type 'IGreeter list' does not have any proper subtypes and need not be used as the target of a static coercion
Error FS0193: Type constraint mismatch. The type Human list is not compatible with type IGreeter list The type 'IGreeter' does not match the type 'Human'
答案 0 :(得分:3)
正如规范所述,F#不支持通用方差:
14.5.2解决子类型约束
注意:F#泛型类型不支持协方差或逆变。 也就是说,虽然CLI中的一维数组类型是 有效协变,F#将这些类型视为不变的 约束解决。同样,F#将CLI委托类型视为 不变并忽略泛型上的任何CLI方差类型注释 接口类型和通用委托类型。
您必须强制转换列表中的元素并创建一个新元素:
let greeters = humans |> List.map (fun h -> h :> IGreeter)