我有一个令人烦恼的错误。
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?
答案 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