从F#调用C#函数

5
我正在尝试从F#调用此函数。
函数签名如下: http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.cloudstorageaccount.setconfigurationsettingpublisher.aspx
CloudStorageAccount.SetConfigurationSettingPublisher
      (Action<string, Func<string, bool>>) : unit

C#的调用大致如下:
CloudStorageAccount.SetConfigurationSettingPublisher((configName,
                                                  configSettingPublisher) =>
{
    string configValue = "something"
    configSettingPublisher(configValue);
});

相比之下,在F#中我需要这样做:

let myPublisher configName (setter:Func<string, bool>) =
    let configValue = RoleEnvironment.GetConfigurationSettingValue(configName)
    setter.Invoke(configName) |> ignore

let act = new Action<string, Func<string, bool>>(myPublisher)

CloudStorageAccount.SetConfigurationSettingPublisher(act)

这段代码能否用F#更加简洁地实现?

1个回答

13

F#会自动将使用fun ... -> ...语法创建的lambda函数转换为.NET委托类型,例如Action。这意味着您可以直接将lambda函数作为参数传递给SetConfigurationSettingPublisher,例如:

CloudStorageAccount.SetConfigurationSettingPublisher(fun configName setter ->
    let configValue = RoleEnvironment.GetConfigurationSettingValue(configName)
    setter.Invoke(configName) |> ignore)
一个有多个参数的函数可以转换为一个有多个参数的委托(参数不应被视为元组)。setter 的类型仍然是 Func<...> 而不是一个简单的 F# 函数,所以你需要使用 Invoke 方法来调用它(但这不应该是个大问题)。
如果你想把 setterFunc<string, bool> 转换成 F# 函数 string -> bool,你可以定义一个简单的活动模式:
let (|Func2|) (f:Func<_, _>) a = f.Invoke(a)

然后你可以写:

TestLib.A.SetConfigurationSettingPublisher(fun configName (Func2 setter) ->
    let configValue = "aa"
    setter(configName) |> ignore)

1
请注意,“自动转换”仅适用于方法参数。 - Brian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接