【问题标题】:F# and interface-implemented membersF# 和接口实现的成员
【发布时间】:2013-01-13 15:57:20
【问题描述】:

我有一个令人烦恼的错误。

type Animal =

    abstract member Name : string

type Dog (name : string) =

    interface Animal with

        member this.Name : string =
            name

let pluto = new Dog("Pluto")
let name = pluto.Name

最后一行,特别是“名称”会生成一个编译器错误,指出“未定义字段、构造函数或成员‘名称’”。

我使用的解决方法是写

let name = (pluto :> Animal).Name

但是,这很烦人,并且会产生很多视觉噪音。在 F# 中是否可以在不明确告诉编译器 Name 是 Animal 类型的派生成员的情况下解析 Name ?

【问题讨论】:

    标签: interface f# overloading overload-resolution explicit-interface


    【解决方案1】:

    在 F# 中,当您实现一个接口时,它相当于 explicit interface implementation in C#。即可以通过接口调用方法,但不能直接通过类调用。

    F# reference article about interfaces 建议添加一个对类型进行向上转换的方法:

    type Dog (name : string) =
    
        member this.Name = (this :> Animal).Name
    
        interface Animal with
            member this.Name : string = name
    

    或者,正如 Daniel 所建议的,你可以反过来做,这意味着你可以避免这种演员:

    type Dog (name : string) =
    
        member this.Name = name
    
        interface Animal with
            member this.Name : string = this.Name
    

    此外,.Net 接口名称的约定是以I 开头,因此您的接口应称为IAnimal

    【讨论】:

    • 如果将逻辑放在类成员中并从接口实现中调用它,则可以避免强制转换。我认为这在概念上也更有意义。
    【解决方案2】:

    另一种选择是使用abstract class 而不是接口:

    [<AbstractClass>]
    type Animal () =
        abstract Name : string
    
    type Dog (name) = 
        inherit Animal()
        override dog.Name = name
    
    let pluto = Dog("Pluto")
    let name = pluto.Name
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多