Ste*_*mer 3 f# class-library c#-to-f#
我有F#类库程序集,它包含两个函数:
let add a b = a + b
和
let rec aggregateList list init (op:int -> int -> int) =
    match list with
    |[] -> init
    |head::tail ->
        let rest = aggregateList tail init op
        op rest head
我有一个C#控制台应用程序,它引用了F#库并尝试执行以下操作:
FSharpList<int> l = new FSharpList<int>(1, new FSharpList<int>(2, FSharpList<int>.Empty));
int result = myFsLibrary.aggregateList(l, 0, myFsLibrary.add);
但是,编译器抱怨[myFsLibrary.add]无法从'方法组'转换为 FSharpFunc<int, FSharpFunc<int, int>>
其他人提供了答案,但我会介入说你不应该这样做.
不要将F#列表暴露给C#.不要将curried函数暴露给C#.阻抗不匹配在此边界处是可见的,因此最好在跨语言汇编边界处公开常见的框架类型.看到
了解更多建议.
您可以使用FSharpFunc委托显式创建函数.在C#中,创建将所有参数作为元组的函数更方便,因此您可以这样做,然后使用函数将函数转换为curry类型FuncConvert.就像是:
FuncConvert.FuncFromTupled(new FSharpFunc<Tuple<int, int>, int>(args => 
    arags.Item1 + args.Item2))
但是,如果需要从C#代码中调用一些F#函数,建议使用C#友好接口公开函数.在这种情况下,我可以使用Func委托,第一个参数应该是IEnumerableF#特定的列表类型:
module List = 
    let AggregateListFriendly inp init (op:Func<int, int, int>) =
        aggregateList (List.ofSeq inp) init (fun a b -> op.Invoke(a, b))
然后你的C#appplication可以使用:
List.AggregateListFriendly(Enumerable.Range(0, 10), 0, (a, b) => a + b));