17

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

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 而无需明确告诉编译器 Name 是 Animal 类型的派生成员?

4

2 回答 2

25

在 F# 中,当您实现接口时,它相当于C# 中的显式接口实现。即可以通过接口调用方法,但不能直接通过类。

关于接口的 F# 参考文章建议添加一个对类型进行向上转换的方法:

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

于 2013-01-29T23:29:41.410 回答
7

另一种选择是使用抽象类而不是接口:

[<AbstractClass>]
type Animal () =
    abstract Name : string

type Dog (name) = 
    inherit Animal()
    override dog.Name = name

let pluto = Dog("Pluto")
let name = pluto.Name
于 2013-01-31T08:15:52.970 回答