F#接口和属性

时间:2015-08-05 07:04:54

标签: interface f# 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 ()

The documentation for F# properties似乎表明我在MyType中实现MyProp是正确的,但是,编译器抱怨“未定义值或构造函数'MyProp'”。有什么想法吗?

3 个答案:

答案 0 :(得分:14)

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

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

如果您明确地实现了接口,那么在C#中会出现相同的错误,并且还需要使用强制转换来访问该成员:

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

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

    void IMyInterface.MyMethod()
    {
        if (((IMyInterface)this).MyProp) { }
    }
}

答案 1 :(得分: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()

由于self中的type MyType() as self标记,代码也比成员版本更清晰,因为imo 只需要访问成员 - 可以直接从界面访问let-bound值。

答案 2 :(得分:4)

这是一个工作版本:

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()

请注意我包含了明确的成员,因为你肯定会错过他们;)