从F#调用C#函数

本文关键字:函数 调用 | 更新日期: 2023-09-27 18:00:54

我试图从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#写得更简洁吗?

从F#调用C#函数

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)