首页 文章

F#和接口实现的成员

提问于
浏览
12

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

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

最后一行,特别是“Name”生成编译器错误,指出“未定义字段,构造函数或成员'Name'” .

我用过的解决方法是写

let name = (pluto :> Animal).Name

然而,这非常烦人并且产生许多视觉噪音 . 是否可以在F#中做一些事情,只是能够解析Name而不明确告诉编译器Name是Animal类型的派生成员?

2 回答

  • 6

    在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
    

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

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

    此外,接口名称的.Net约定是使用 I 启动它们,因此您的接口应该被称为 IAnimal .

  • 21

    另一种选择是使用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
    

相关问题