F#:使用重载成员实现接口
F#: Implementing an interface with overloaded members
我在 F# 中用重载方法定义了一个接口。根据编译器的要求,重载使用元组参数而不是柯里化参数:
type IInterface =
abstract member Do : (int * string) -> unit
abstract member Do : int -> unit
然后我创建一个 class 来实现接口:
type ImplementingClass =
interface IInterface with
member this.Do (i, s) = ()
member this.Do i = ()
但是,这样做会为两种方法中的第一种产生编译器错误:"This override takes a different number of arguments to the corresponding abstract member"
我做错了什么?
以下两者有细微差别:
abstract member Do : int * string -> unit
abstract member Do : (int * string) -> unit
如果添加括号,则表示参数是一个元组,编译器应该生成采用 Tuple<int, string>
的方法。如果没有括号,该方法将被编译为采用两个参数。大多数时候,这是隐藏的,您可以忽略它 - 但遗憾的是,并非总是如此。
因此,您可以更改接口定义以使用普通的 "two-parameter" 方法(这是我的首选方法 - 您仍然可以使用元组作为参数调用该方法,并且在 .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) = ()
遗憾的是,这有点难看 - 您需要类型注释,以便编译器可以明确地决定您要实现的方法。
我在 F# 中用重载方法定义了一个接口。根据编译器的要求,重载使用元组参数而不是柯里化参数:
type IInterface =
abstract member Do : (int * string) -> unit
abstract member Do : int -> unit
然后我创建一个 class 来实现接口:
type ImplementingClass =
interface IInterface with
member this.Do (i, s) = ()
member this.Do i = ()
但是,这样做会为两种方法中的第一种产生编译器错误:"This override takes a different number of arguments to the corresponding abstract member"
我做错了什么?
以下两者有细微差别:
abstract member Do : int * string -> unit
abstract member Do : (int * string) -> unit
如果添加括号,则表示参数是一个元组,编译器应该生成采用 Tuple<int, string>
的方法。如果没有括号,该方法将被编译为采用两个参数。大多数时候,这是隐藏的,您可以忽略它 - 但遗憾的是,并非总是如此。
因此,您可以更改接口定义以使用普通的 "two-parameter" 方法(这是我的首选方法 - 您仍然可以使用元组作为参数调用该方法,并且在 .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) = ()
遗憾的是,这有点难看 - 您需要类型注释,以便编译器可以明确地决定您要实现的方法。