F#和接口实现的成员

时间:2013-01-29 23:08:40

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

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

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是Animal类型的派生成员的情况下解析Name?

2 个答案:

答案 0 :(得分:22)

在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

答案 1 :(得分:7)

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