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

时间:2016-11-28 18:04:00

标签: c# f# mono c#-to-f#

我在F#中使用这个泛型函数,使用( - )运算符:

let inline sub a b = a - b

现在我从C#调用此函数:

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

这会引发错误:

  

未处理的异常:System.NotSupportedException:指定的方法是   不支持。在ProjA.MainClass.Main(System.String [] args)   [0x00000]在&lt; 4f209fa43741462db3b8f73ac83c35a2&gt;中:0 [ERROR]致命   UNHANDLED EXCEPTION:System.NotSupportedException:指定的方法是   不支持。在ProjA.MainClass.Main(System.String [] args)   [0x00000]在&lt; 4f209fa43741462db3b8f73ac83c35a2&gt;:0

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

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

2)有没有办法克服这个问题(但是我需要使用inline关键字来使这个函数通用)?

3)从c#调用f#函数时,你是否经历过类似的事情,你是如何解决它的?

我在macOS Sierra上使用Mono 4.8。

1 个答案:

答案 0 :(得分:7)

通常,声明为inline的函数将无法与其他语言一起使用(或与F#不同)。它们在调用站点被替换为F#编译器的一个特性,C#和其他CLR语言不支持它。这是F#相对于其他语言的重要优势。

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

这实际上是C#中的限制,导致人们多年来要求IArithmetic(*使用Internet Archive,因为它已隐藏在Connect中)之类的内容。 F#通过statically resolved type parameters解决此问题,但这是一个特定于F#的功能,并且无法使用C#和其他语言。通过F#包装函数不会在C#中启用它。