C# · 12月 28, 2021

运算符( – )用于F#raise中指定方法不支持异常来自C#

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

让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)我做错了,这是一个bug吗?

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

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

我在MacOS Sierra上使用Mono 4.8.

解决方法 一般来说,声明为inline的函数将不能用于其他语言(或不能与F#一样).它们在调用站点被替换为F#编译器的一个特性,C#和其他CLR语言不支持.这是F#超过这些其他语言的显着优势.

但是,有一些例外.可以编写基于运行时类型执行分派的F#内联函数,然后可以从C#和其他语言使用.通常,这些从C#使用时不会得到相同的IL,因为它们对于某些类型(对于原始类型的特定处理程序将不被处理).这就是为什么()工作 – 你可以看到this in the code for the operator,where()调用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#中启用.