我在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 = ()
但是,这样做会导致两种方法中的第一种产生编译器错误:“此覆盖对相应的抽象成员采用不同数量的参数”
我在这里做错了什么?
答案 0 :(得分: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) = ()
可悲的是,这有点难看 - 你需要类型注释,以便编译器可以明确地决定你正在实现哪种方法。