给出以下片段:
type Foo() =
static member Test (act : unit -> unit) = act()
static member Test (act : Action) = Foo.Test act.Invoke
我在最后一行说明错误:无法根据此程序点之前的类型信息确定方法'Test'的唯一重载。可能需要类型注释。
不幸的是,类型注释(act.Invoke : unit -> unit)
无法解决歧义,我找不到可以修复它的注释。我希望Action
版本成为->
版本的包装器。我的特定用例是定义一个将从F#和C#调用的类,所以我希望它能从两种语言本地工作。
答案 0 :(得分:4)
F#为您转换Action
转换,因此您可以(理论上)使用一种方法。
type Foo() =
static member Test (act : Action) = act.Invoke()
Foo.Test (fun () -> ())
我无法弄清楚如何强制编译器在Action
和unit -> unit
之间进行选择。另外两个选择:
Action
重载为主要内容并执行Foo.Test(Action(act))
但我的推荐是采用Action
的单一方法。由于转换是自动的,因此在某种意义上,互操作是免费的。
答案 1 :(得分:1)
正如Daniel所说,你可能只是跳过第一次重载,因为当一个带有委托的方法应用于F#函数值时,F#会自动插入一个委托构造函数(参见规范8.13.6部分)。 / p>
如果你真的想要定义一个与你的例子具有相同表面区域的类型,你可以利用let-bound函数不包括类型导向转换的事实(只有方法调用这样做):
type Foo() =
static let test act : unit = act()
static member Test act = test act
static member Test (act : System.Action) = test act.Invoke
但这样做并不是很有用,因为如果在尝试定义第二个重载时尝试从类外部调用第一个重载,则会遇到同样的问题。