在 F# 中,如何实现具有父接口和祖父接口的接口?
In F#, how to implement an interface with parent and grandparent interfaces?
当继承多个接口时,在 F# 中实现它们的正确方法是什么?
例如,假定以下接口层次结构,ITranscript 在 TranscriptNote 类型上的实现给出:
“值或构造函数'tservice'未定义。”
type TranscriptNote =
{
tservice : Nullable<DateTime>
}
interface ITranscript with
member this.tservice with get() = tservice and set value = tservice <- value
"The value or constructor 'tservice' is not defined."
where ITranscript is :
type ITranscript =
inherit ITablet
abstract member note : byte[] with get
abstract member transcript: string with get
type ITablet =
inherit IParagraph
inherit IInk
type IParagraph =
inherit IEncounter
abstract member paragraphTitle : string with get
abstract member title : string with get
type IEncounter =
abstract member tservice : Nullable<DateTime> with get,set
提前感谢您的帮助。
更新:@JL0PD 对您看到的编译器错误有正确的解释。我已经从我的答案中删除了不正确的信息,但保留了其余信息。
一种方法是分别实现每个接口。在每个接口下,仅实现该接口明确定义的成员:
type IGrandparent =
abstract member GetName : unit -> string
type IParent =
inherit IGrandparent
abstract member GetCount : unit -> int
type MyType() =
interface IGrandparent with
member __.GetName() = "name"
interface IParent with
member __.GetCount() = 1
let obj = MyType() :> IParent
printfn "%A" <| obj.GetName()
printfn "%A" <| obj.GetCount()
请注意,我没有在 IParent
下实现 GetName
,但由于继承,我仍然可以在 IParent
实例上调用 GetName
。
如果你想用原始结构编译它,你的类型应该是这样的。但即使 F# 支持 OOP,也并不意味着那总是最好的方式,阅读 style guide P 3 & 4. F# is not C# with different syntax, it's different language with different core principles. Maybe your hierarchy can be represented better with DU
// [<CLIMutable>] // uncomment this line to make all fields mutable
type TranscriptNote =
{
// instances can be mutated, but only this field
mutable tservice : Nullable<DateTime>
}
interface ITranscript with
// stubs
member _.note = [| |] // empty array
member _.paragraphTitle = "some title"
member _.title = "some another title"
member _.transcript = "some transcript"
member this.tservice with get() = this.tservice // need 'this' to get access to field
and set value = this.tservice <- value
注意:您不必单独实现每个接口,但它可能有助于维护。
当继承多个接口时,在 F# 中实现它们的正确方法是什么?
例如,假定以下接口层次结构,ITranscript 在 TranscriptNote 类型上的实现给出:
“值或构造函数'tservice'未定义。”
type TranscriptNote =
{
tservice : Nullable<DateTime>
}
interface ITranscript with
member this.tservice with get() = tservice and set value = tservice <- value
"The value or constructor 'tservice' is not defined."
where ITranscript is :
type ITranscript =
inherit ITablet
abstract member note : byte[] with get
abstract member transcript: string with get
type ITablet =
inherit IParagraph
inherit IInk
type IParagraph =
inherit IEncounter
abstract member paragraphTitle : string with get
abstract member title : string with get
type IEncounter =
abstract member tservice : Nullable<DateTime> with get,set
提前感谢您的帮助。
更新:@JL0PD 对您看到的编译器错误有正确的解释。我已经从我的答案中删除了不正确的信息,但保留了其余信息。
一种方法是分别实现每个接口。在每个接口下,仅实现该接口明确定义的成员:
type IGrandparent =
abstract member GetName : unit -> string
type IParent =
inherit IGrandparent
abstract member GetCount : unit -> int
type MyType() =
interface IGrandparent with
member __.GetName() = "name"
interface IParent with
member __.GetCount() = 1
let obj = MyType() :> IParent
printfn "%A" <| obj.GetName()
printfn "%A" <| obj.GetCount()
请注意,我没有在 IParent
下实现 GetName
,但由于继承,我仍然可以在 IParent
实例上调用 GetName
。
如果你想用原始结构编译它,你的类型应该是这样的。但即使 F# 支持 OOP,也并不意味着那总是最好的方式,阅读 style guide P 3 & 4. F# is not C# with different syntax, it's different language with different core principles. Maybe your hierarchy can be represented better with DU
// [<CLIMutable>] // uncomment this line to make all fields mutable
type TranscriptNote =
{
// instances can be mutated, but only this field
mutable tservice : Nullable<DateTime>
}
interface ITranscript with
// stubs
member _.note = [| |] // empty array
member _.paragraphTitle = "some title"
member _.title = "some another title"
member _.transcript = "some transcript"
member this.tservice with get() = this.tservice // need 'this' to get access to field
and set value = this.tservice <- value
注意:您不必单独实现每个接口,但它可能有助于维护。