F#和接口实现的成员

Ben*_*sen 13 f# overloading interface explicit-interface overload-resolution

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

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
Run Code Online (Sandbox Code Playgroud)

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

我用过的解决方法是写

let name = (pluto :> Animal).Name
Run Code Online (Sandbox Code Playgroud)

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

svi*_*ick 22

在F#中,当您实现一个接口时,它相当于C#中的显式接口实现.也就是说,您可以通过接口调用该方法,但不能直接通过该类调用.

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

type Dog (name : string) =

    member this.Name = (this :> Animal).Name

    interface Animal with
        member this.Name : string = name
Run Code Online (Sandbox Code Playgroud)

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

type Dog (name : string) =

    member this.Name = name

    interface Animal with
        member this.Name : string = this.Name
Run Code Online (Sandbox Code Playgroud)

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

  • 如果将逻辑放在类成员中并从接口实现中调用它,则可以避免强制转换.我认为它在概念上也更有意义. (7认同)

Phi*_*ord 7

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

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

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

let pluto = Dog("Pluto")
let name = pluto.Name
Run Code Online (Sandbox Code Playgroud)