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

mat*_*wko 10 c# mono f# c#-to-f#

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

let inline sub a b = a - b

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

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

这引发了一个错误:

未处理的异常:System.NotSupportedException:不支持指定的方法.在<4f209fa43741462db3b8f73ac83c35a2>中的ProjA.MainClass.Main(System.String [] args)[0x00000]:0 [错误]致命未处理的异常:System.NotSupportedException:不支持指定的方法.at ProjA.MainClass.Main(System.String [] args)[0x00000] in <4f209fa43741462db3b8f73ac83c35a2>:0

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

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

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

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

我在macOS Sierra上使用Mono 4.8.

Ree*_*sey 7

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

但是,也有一些例外.可以编写F#内联函数,这些函数根据运行时类型执行调度,然后可以从C#和其他语言中使用.通常,当从C#使用它们时,它们将不会获得与F#相同的IL(对于某些类型)(原始类型的特定处理程序将不会被处理).这就是为什么(+)有效 - 您可以在运算符的代码中看到这一点,其中(+)调用AdditionDynamic<(^T),(^U),(^V)> x y.请注意,(-) 缺少运行时调度版本,并且明确标记为[<NoDynamicInvocation>],这就是它无法在C#中工作的原因.

这实际上是C#中的相同限制,导致人们多年来要求像IArithmetic(*使用Internet Archive,因为它已隐藏在Connect中)之类的东西.F#通过静态解析的类型参数解决这个问题,但这是F#特有功能,不能用于C#和其他语言.通过F#包装函数不会在C#中启用它.