从F#调用C#函数

Bal*_*ala 4 c# f#

我试图从f#调用这个函数

http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.cloudstorageaccount.setconfigurationsettingpublisher.aspx

功能签名是:

CloudStorageAccount.SetConfigurationSettingPublisher
      (Action<string, Func<string, bool>>) : unit
Run Code Online (Sandbox Code Playgroud)

C#调用是这样的:

CloudStorageAccount.SetConfigurationSettingPublisher((configName,
                                                  configSettingPublisher) =>
{
    string configValue = "something"
    configSettingPublisher(configValue);
});
Run Code Online (Sandbox Code Playgroud)

而在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)
Run Code Online (Sandbox Code Playgroud)

这可以在f#中更简洁地写出来吗?

Tom*_*cek 13

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

CloudStorageAccount.SetConfigurationSettingPublisher(fun configName setter ->
    let configValue = RoleEnvironment.GetConfigurationSettingValue(configName)
    setter.Invoke(configName) |> ignore)
Run Code Online (Sandbox Code Playgroud)

可以将多个参数的函数转换为多个参数的委托(不应将参数视为元组).类型setter仍然是Func<...>一个简单的F#函数,所以你需要使用该Invoke方法调用它(但这不应该是一个大问题).

如果你要打开setterFunc<string, bool>一个F#的功能string -> bool,你可以定义一个简单的主动模式:

let (|Func2|) (f:Func<_, _>) a = f.Invoke(a)
Run Code Online (Sandbox Code Playgroud)

......然后你可以写:

TestLib.A.SetConfigurationSettingPublisher(fun configName (Func2 setter) ->
    let configValue = "aa"
    setter(configName) |> ignore)
Run Code Online (Sandbox Code Playgroud)