F#接口和属性

Eyv*_*ind 8 f# interface automatic-properties

我试图抓住F#,在这个过程中我正在转换一些C#代码.我在界面中定义属性并在类型中实现它们时遇到了一些麻烦.

请考虑以下代码:

module File1

type IMyInterface =
    abstract member MyProp : bool with get, set
    abstract member MyMethod : unit -> unit

type MyType() = 
    interface IMyInterface with
        member val MyProp = true with get, set
        member self.MyMethod() = if MyProp then () else ()
Run Code Online (Sandbox Code Playgroud)

F#属性的文档似乎表明我在MyType中的MyProp实现是正确的,但是,编译器抱怨"未定义值或构造函数'MyProp'".有任何想法吗?

Phi*_*ord 14

要在(显式)接口中访问属性,您需要转换self为对接口类型的引用:

type MyType() = 
    interface IMyInterface with
        member val MyProp = true with get, set
        member self.MyMethod() = if (self :> IMyInterface).MyProp then () else ()
Run Code Online (Sandbox Code Playgroud)

如果明确实现接口,则在C#中会出现相同的错误,并且还需要强制转换才能访问该成员:

interface IMyInterface
{
    bool MyProp { get; set; }
    void MyMethod();
}

class MyType : IMyInterface
{
    bool IMyInterface.MyProp { get; set; }

    void IMyInterface.MyMethod()
    {
        if (((IMyInterface)this).MyProp) { }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 据我所知,在F#中必须明确实现所有接口.Scott很好地解释了这里http://fsharpforfunandprofit.com/posts/interfaces/ (3认同)

Gru*_*oon 8

如果只访问接口,则无需在类型本身中定义成员.如果你想要极简主义,菲尔的答案是好的,但我喜欢的另一种方法是使用"let-bound"值而不是成员 - 对于更复杂的代码,类型推断更好,并且它们通常比成员更容易处理.

type MyType() = 
    let mutable myProp = true 
    let myMethod() = if myProp then () else ()

    interface IMyInterface with
        member __.MyProp with get() = myProp and set v = myProp <- v
        member __.MyMethod() = myMethod()
Run Code Online (Sandbox Code Playgroud)

代码比成员版本更简洁,imo,因为 只有访问成员才需要self标记- 可以直接从界面访问let-bound值.type MyType() as self


Car*_*ten 5

这是一个工作版本:

type IMyInterface =
    abstract member MyProp : bool with get, set
    abstract member MyMethod : unit -> unit

type MyType() = 
    member val MyProp = true with get, set
    member self.MyMethod() = if self.MyProp then () else ()
    interface IMyInterface with
        member self.MyProp with get () = self.MyProp and set v = self.MyProp <- v
        member self.MyMethod() = self.MyMethod()
Run Code Online (Sandbox Code Playgroud)

请注意,我包含了显式成员,因为您肯定会错过它们;)

  • @Eyvind 根据我的经验,F# 在功能上使用时非常优雅,但在以面向对象的方式使用时会变得“混乱”。这会激励你去寻找好的功能设计:) (2认同)