F# 和接口实现的成员
Posted
技术标签:
【中文标题】F# 和接口实现的成员【英文标题】:F# and interface-implemented members 【发布时间】:2013-01-13 15:57:20 【问题描述】:我有一个令人烦恼的错误。
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 是 Animal 类型的派生成员的情况下解析 Name ?
【问题讨论】:
【参考方案1】:在 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
或者,正如 Daniel 所建议的,你可以反过来做,这意味着你可以避免这种演员:
type Dog (name : string) =
member this.Name = name
interface Animal with
member this.Name : string = this.Name
此外,.Net 接口名称的约定是以I
开头,因此您的接口应称为IAnimal
。
【讨论】:
如果将逻辑放在类成员中并从接口实现中调用它,则可以避免强制转换。我认为这在概念上也更有意义。【参考方案2】:另一种选择是使用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
【讨论】:
以上是关于F# 和接口实现的成员的主要内容,如果未能解决你的问题,请参考以下文章