从C#调用带函数参数的F#函数:多参Logger适配问题
解决C#调用F#多参数函数的适配问题
这个问题的核心在于F#函数的柯里化特性——F#里的多参数函数本质上是嵌套的单参数函数(比如string -> string -> unit等价于string -> (string -> unit)),而C#的普通多参数方法是元组式的,直接用FuncConvert.ToFSharpFunc只能处理单参数委托,所以会出现适配问题。
下面是两种可行的解决方案:
方法1:手动柯里化后转换
先把C#的多参数方法包装成柯里化的嵌套委托,再用FuncConvert.ToFSharpFunc转换成F#函数类型:
完整代码示例
F# 端的Fetch函数
let Fetch logger id = logger "string1" "string2" // 这里替换成你的数据库查询逻辑,示例返回id的字符串形式 id.ToString()
C# 端的调用代码
using Microsoft.FSharp.Core; public class FetchConsumer { // 你的Mock logger实现 private void Print(string x, string y) { // 可以添加调试输出或者空实现 System.Console.WriteLine($"Mock logger received: {x}, {y}"); } public void CallFSharpFetch() { // 1. 将Print包装成柯里化的委托:接受第一个string,返回接受第二个string的函数 Func<string, Func<string, Unit>> curriedLogger = x => y => { Print(x, y); return Unit.Default; // F#的unit对应C#的Unit类型 }; // 2. 转换成F#函数类型 var fsharpLogger = FuncConvert.ToFSharpFunc(curriedLogger); // 3. 调用F#的Fetch函数 var result = Fetch(fsharpLogger, 3); } }
方法2:直接创建嵌套的FSharpFunc
利用FSharpFunc的静态FromFunc方法,直接构建嵌套的F#函数结构,更贴合F#的函数模型:
using Microsoft.FSharp.Core; public class FetchConsumer { private void Print(string x, string y) { System.Console.WriteLine($"Mock logger received: {x}, {y}"); } public void CallFSharpFetch() { // 直接构建嵌套的FSharpFunc,对应F#的string -> string -> unit类型 var fsharpLogger = FSharpFunc<string, FSharpFunc<string, Unit>>.FromFunc(x => FSharpFunc<string, Unit>.FromFunc(y => { Print(x, y); return Unit.Default; }) ); var result = Fetch(fsharpLogger, 3); } }
关键说明
- 必须引用
FSharp.CoreNuGet包,才能使用FuncConvert、FSharpFunc和Unit这些类型; - F#的
unit类型对应C#的Microsoft.FSharp.Core.Unit,需要返回Unit.Default来匹配; - 两种方法的本质都是将C#的元组式多参数方法,转换成F#要求的柯里化嵌套函数结构。
内容的提问来源于stack exchange,提问作者Shane Fleming
相关产品推荐
相关产品推荐

