>我有以下 F# 函数
let Fetch logger id =
logger "string1" "string2"
// search a database with the id and return a result
在我的 C# 类中,我想调用 Fetch F# 函数来模拟记录器函数。所以我有以下 C# 函数作为模拟器。
void Print(string x, string y) { // do nothing }
我正在尝试使用以下方法从 C# 类调用 F# 函数。
var _logger = FuncConvert.ToFSharpFunc<string, string>(Print);
var _result = Fetch(logger, 3);
FuncConvert.ToFSharpFunc 的问题在于只接受一个类型参数。当我将 Fetch F# 记录器函数更改为以下内容时,当我使用 ToFSharpFunc(Print( 时,它工作正常,其中 C# 打印函数也接受一个字符串。
let Fetch logger id =
logger "string1"
// search a database with the id and return a result
有人有想法吗?
简短版本
var tupleLogger = FuncConvert.ToFSharpFunc<Tuple<string,string>>(t=>Print(t.Item1,t.Item2));
var logger = FuncConvert.FuncFromTupled(tupleLogger);
MyOtheProject.MyModule.Fetch(logger, 3);
长版本
F# 函数只接受一个参数。多个参数实质上创建嵌套函数。你需要在 C# 方面做同样的事情。
使用智能感知检查 C# 中 logger
参数的类型。它
Microsoft.FSharp.Core.FSharpFunc<string, Microsoft.FSharp.Core.FSharpFunc<string, a>>
FuncConvert.ToFSharpFunc 无法创建这个。FuncFromTupled虽然可以从FSharpFunc创建它,该FSharpFunc将具有多个字段的元组作为参数。
这是ToFsharpFunc可以创建的东西:
FSharpFunc<Tuple<string,string>,Unit> tupleLogger = FuncConvert.ToFSharpFunc<Tuple<string,string>>(
t=> Print(t.Item1,t.Item2));
或
var tupleLogger = FuncConvert.ToFSharpFunc<Tuple<string,string>>(t=> Print(t.Item1,t.Item2));
正如FuncFromTupled
的描述所说,这是A utility function to convert function values from tupled to curried form.
。 tupleLogger
是一个需要转换为柯里形式:
var logger = FuncConvert.FuncFromTupled(tupleLogger);
生成的代码如下所示:
var tupleLogger = FuncConvert.ToFSharpFunc<Tuple<string,string>>(t=>Print(t.Item1,t.Item2));
var logger = FuncConvert.FuncFromTupled(tupleLogger);
MyOtheProject.MyModule.Fetch(logger, 3);
您可以创建一个实用程序函数来组合这两个转换:
public static class MyFuncConvert
{
public static FSharpFunc<T1, FSharpFunc<T2, Unit>> ToFSharpFunc<T1, T2>(Action<T1, T2> action)
{
var tupled = FuncConvert.ToFSharpFunc<Tuple<T1, T2>>(
t => action(t.Item1, t.Item2));
var curried = FuncConvert.FuncFromTupled(tupled);
return curried;
}
}
这将允许您编写:
var logger = MyFuncConvert.ToFSharpFunc<string,string>(Print);
F# 函数只能有一个参数。例如,当您有:logger "string1" "string2"
表达式时,logger "string1"
创建另一个包含"string1"
的函数,然后可以将"string2"
作为参数。因此,要转换它,您可以创建这样的辅助方法:
public static class FuncConvertExt
{
public static FSharpFunc<T1, FSharpFunc<T2, Unit>> Create<T1, T2>(Action<T1, T2> action)
{
Converter<T1, FSharpFunc<T2, Unit>> conv = value1 =>
{
return FuncConvert.ToFSharpFunc<T2>(value2 => action(value1, value2));
};
return FSharpFunc<T1, FSharpFunc<T2, Unit>>.FromConverter(conv);
}
}
然后你可以这样做:
var func = FuncConvertExt.Create<string, string>(Print);
func.Invoke("aaa").Invoke("bbb");
更多信息: https://blogs.msdn.microsoft.com/jaredpar/2010/07/27/converting-system-funct1-tn-to-fsharpfuncttresult/