C#与F#互操作:如何获取结果而非FSharpFunc
解决F#类库函数被C#调用返回FSharpFunc的问题
问题原因
你写的F#函数存在逻辑疏漏:Seq.filter是柯里化函数,签名为('a -> bool) -> seq<'a> -> seq<'a>,执行Seq.filter(fun x -> x % 2 = 0)后,得到的是一个等待接收序列参数的函数(类型为seq<int> -> seq<int>)。而你的FilterEvenNumbers函数虽声明了input参数,但函数体未使用该参数,直接返回了这个未完成的柯里化函数。因此C#调用时传入的numbers被忽略,返回的自然是F#的函数对象。
解决方案
修正F#函数写法,让它真正处理输入序列并返回过滤结果:
方法1:显式传入输入序列
直接把input传给Seq.filter的结果,完成柯里化调用:
let FilterEvenNumbers input = Seq.filter(fun x -> x % 2 = 0) input
方法2:用管道操作符简化写法
借助F#管道操作符提升代码可读性:
let FilterEvenNumbers input = input |> Seq.filter(fun x -> x % 2 = 0)
方法3:无参数柯里化函数写法
若想保留柯里化风格,同时让C#直接获取结果,可这样写(本质与方法1一致):
let FilterEvenNumbers = Seq.filter(fun x -> x % 2 = 0)
此时C#传入的参数会直接作为Seq.filter所需的序列参数,返回值即为过滤后的IEnumerable<int>。
验证C#调用
修正后原C#代码无需修改,调用后可直接得到预期序列:
var numbers = new int[] { 1, 2, 3, 4 }; var filteredNumbers = MyFSharpLibrary.FilterEvenNumbers(numbers); // filteredNumbers 为 IEnumerable<int>,包含2和4
内容的提问来源于stack exchange,提问作者tommyk
相关产品推荐
相关产品推荐

