我试图从f#
调用此函数功能签名是:
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#中更简洁地写出来吗?
答案 0 :(得分: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
方法调用它(但这不应该是一个大问题。)
如果您想将setter
从Func<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)