Action和unit之间重载决策的模糊性 - > F#中的单位类型

时间:2012-04-17 20:26:33

标签: f#

给出以下片段:

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#调用的类,所以我希望它能从两种语言本地工作。

2 个答案:

答案 0 :(得分:4)

F#为您转换Action转换,因此您可以(理论上)使用一种方法。

type Foo() =
    static member Test (act : Action) = act.Invoke()

Foo.Test (fun () -> ())

我无法弄清楚如何强制编译器在Actionunit -> unit之间进行选择。另外两个选择:

  1. 使Action重载为主要内容并执行Foo.Test(Action(act))
  2. 将逻辑放在从公共方法
  3. 调用的第三个函数中

    但我的推荐是采用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

但这样做并不是很有用,因为如果在尝试定义第二个重载时尝试从类外部调用第一个重载,则会遇到同样的问题。