将列表转换为超类列表

时间:2014-04-26 18:48:35

标签: .net f#

假设我定义了以下接口和实现它的类:

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'

1 个答案:

答案 0 :(得分:3)

正如规范所述,F#不支持通用方差:

14.5.2解决子类型约束

  

注意:F#泛型类型不支持协方差或逆变。   也就是说,虽然CLI中的一维数组类型是   有效协变,F#将这些类型视为不变的   约束解决。同样,F#将CLI委托类型视为   不变并忽略泛型上的任何CLI方差类型注释   接口类型和通用委托类型。

您必须强制转换列表中的元素并创建一个新元素:

let greeters = humans |> List.map (fun h -> h :> IGreeter)