Вызов функций C# из F#

Я пытался вызвать эту функцию из 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 ответ

Решение

F# автоматически преобразует лямбда-функции, созданные с использованием fun ... -> ... синтаксис для типов делегатов.NET, таких как Action, Это означает, что вы можете использовать лямбда-функцию в качестве аргумента 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)
Другие вопросы по тегам