【问题标题】:Call a higher order F# function from C#从 C# 调用高阶 F# 函数
【发布时间】:2015-06-03 17:54:25
【问题描述】:

给定 F# 高阶函数(在参数中取一个函数):

let ApplyOn2 (f:int->int) = f(2)  

和 C# 函数

public static int Increment(int a) { return a++; } 

如何使用Increment 作为参数调用ApplyOn2(来自C#)? 请注意ApplyOn2 导出为Microsoft.FSharp.Core.FSharpFunc<int,int>Increment 的签名不匹配。

【问题讨论】:

    标签: c# f# delegates


    【解决方案1】:

    要从等效的 C# 函数中获取 FSharpFunc,请使用:

    Func<int,int> cs_func = (i) => ++i;
    var fsharp_func = Microsoft.FSharp.Core.FSharpFunc<int,int>.FromConverter(
        new Converter<int,int>(cs_func));
    

    要从等效的 FSharpFunc 获取 C# 函数,请使用

    var cs_func = Microsoft.FSharp.Core.FSharpFunc<int,int>.ToConverter(fsharp_func);
    int i = cs_func(2);
    

    因此,在这种特殊情况下,您的代码可能如下所示:

    Func<int, int> cs_func = (int i) => ++i;
    int result = ApplyOn22(Microsoft.FSharp.Core.FSharpFunc<int, int>.FromConverter(
                new Converter<int, int>(cs_func)));
    

    【讨论】:

    【解决方案2】:

    如果您想提供更友好的互操作体验,请考虑直接在 F# 中使用 System.Func 委托类型:

    let ApplyOn2 (f : System.Func<int, int>) = f.Invoke(2)
    

    您可以像这样在 C# 中非常轻松地调用您的 F# 函数:

    MyFSharpModule.ApplyOn2(Increment); // 3
    

    但是,您编写的增量函数存在问题。为了让函数返回正确的结果,您需要使用自增运算符的前缀形式:

    public static int Increment(int a) { return ++a; }
    

    【讨论】:

      【解决方案3】:

      只需创建对您的程序集的引用:

      #r @"Path\To\Your\Library.dll"
      let ApplyOn2 (f:int->int) = f(2)
      ApplyOn2 Library.Class.Increment
      

      【讨论】:

      • 问题不在于引用程序集。问题是 ApplyOn2 导出为 Microsoft.FSharp.Core.FSharpFunc 与 Increment 不匹配。
      • 我试过了,效果很好:> ClassLibrary1.Class1.Increment;;将会话绑定到 'J:\Projects\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll'... val it : int -> int = > let ApplyOn2 (f:int->int) = f(2);; val ApplyOn2 : (int -> int) -> int > ApplyOn2 ClassLibrary1.Class1.Increment;;验证它:int = 2
      • @ssp:这是从 F# 调用 C# 的示例。正如您所指出的,F# 对函数和委托类型转换更加宽容,但是,问题是关于从 C# 调用 F#。
      猜你喜欢
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多