F# 中使用的运算符 (-) 引发 C# 不支持指定方法的异常

Operator (-) used in F# raises Specified method is not supported exception from C#

我在 F# 中有这个通用函数,它使用 (-) 运算符:

let inline sub a b = a - b

现在我从 C# 调用这个函数:

int a = sub<int, int, int>(4, 1);

这引发了一个错误:

Unhandled Exception: System.NotSupportedException: Specified method is not supported. at ProjA.MainClass.Main (System.String[] args) [0x00000] in <4f209fa43741462db3b8f73ac83c35a2>:0 [ERROR] FATAL UNHANDLED EXCEPTION: System.NotSupportedException: Specified method is not supported. at ProjA.MainClass.Main (System.String[] args) [0x00000] in <4f209fa43741462db3b8f73ac83c35a2>:0

请注意,这适用于 (+) 运算符或没有 inline 关键字。

1) 我是不是做错了什么或者这是一个错误?

2) 有什么方法可以解决这个问题(但我需要 inline 关键字来使这个函数通用)?

3) 你在c#中调用f#函数时遇到过类似的情况吗,你是怎么解决的?

我在 macOS Sierra 上使用 Mono 4.8。

一般来说,声明为 inline 的函数在其他语言中将无法使用(或者无法像 F# 那样工作)。它们作为 F# 编译器的一项功能在调用站点被替换,C# 和其他 CLR 语言不支持该功能。这是 F# 相对于这些其他语言的显着优势。

但是,也有一些例外。可以编写基于运行时类型执行分派的 F# 内联函数,然后可从 C# 和其他语言中使用。通常,对于某些类型,它们在 C# 中使用时不会获得与在 F# 中使用时相同的 IL(不会处理原始类型的特定处理程序)。这就是 (+) 工作的原因 - 您可以看到 this in the code for the operator, where (+) calls AdditionDynamic<(^T),(^U),(^V)> x y. Note that (-) is missing the runtime dispatched version,并明确标记为 [<NoDynamicInvocation>],这就是它无法在 C# 中工作的原因。

这实际上是 C# 中导致人们请求 IArithmetic (*using Internet Archive since it's been hidden in Connect) for many years. F# works around this via statically resolved type parameters 之类的相同限制,但这是 F# 特有的 功能,将不起作用来自 C# 和其他语言。通过 F# 包装函数不会在 C# 中启用它。