首页 文章

F#:实现具有重载成员的接口

提问于
浏览
5

我在F#中定义了一个带有重载方法的接口 . 根据编译器请求,重载使用了tupled参数而不是curried参数:

type IInterface =
    abstract member Do : (int * string) -> unit
    abstract member Do : int -> unit

然后我创建一个实现接口的类:

type ImplementingClass =
    interface IInterface with
        member this.Do (i, s) = ()
        member this.Do i = ()

但是,这样做会导致两个方法中的第一个出现编译器错误:“此覆盖对相应的抽象成员采用不同数量的参数”

我在这做错了什么?

1 回答

  • 9

    以下两者之间存在细微差别:

    abstract member Do : int * string -> unit
    abstract member Do : (int * string) -> unit
    

    如果添加括号,则表示该参数是一个元组,编译器应生成一个采用 Tuple<int, string> 的方法 . 如果没有括号,该方法将被编译为采用两个参数 . 大多数时候,这是隐藏的,你可以忽略它 - 但可悲的是,并非总是如此 .

    因此,您可以将接口定义更改为使用普通的“双参数”方法(这将是我首选的方法 - 您仍然可以使用tuple作为参数调用该方法,并在.NET / C#视图中看起来更好):

    type IInterface =
        abstract member Do : int * string -> unit
        abstract member Do : int -> unit
    
    type ImplementingClass =
        interface IInterface with
            member this.Do (i, s) = ()
            member this.Do i = ()
    

    或者您可以按原样实现接口:

    type ImplementingClass =
        interface IInterface with
            member this.Do((i:int, s:string)) = ()
            member this.Do(i:int) = ()
    

    遗憾的是,这有点难看 - 您需要类型注释,以便编译器可以明确地决定您正在实现哪种方法 .

相关问题