Оператор (-), используемый в F # raises Указанный метод не поддерживается исключением из С#

У меня есть эта общая функция в F #, которая использует (-) оператор:

let inline sub a b = a - b

Теперь я вызываю эту функцию из С#:

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

Возникает ошибка:

Необработанное исключение: System.NotSupportedException: указанный метод не поддерживается. в ProjA.MainClass.Main(System.String [] args) [0x00000] в < 4f209fa43741462db3b8f73ac83c35a2 > : 0 [ОШИБКА] FATAL НЕПРАВИЛЬНОЕ ИСКЛЮЧЕНИЕ: System.NotSupportedException: указанный метод не поддерживается. в ProjA.MainClass.Main(System.String [] args) [0x00000] в < 4f209fa43741462db3b8f73ac83c35a2 > : 0

Обратите внимание, что это отлично работает для оператора (+) или без встроенного ключевого слова.

1) Я что-то делаю неправильно или это ошибка?

2) Есть ли способ преодолеть эту проблему (но мне нужно встроенное ключевое слово для создания этой общей функции)?

3) Испытывали ли вы что-то подобное при вызове функции f # из С#, как вы его разрешили?

Я использую Mono 4.8 на macOS Sierra.

Ответ 1

В общем случае функции, объявленные как inline, не будут использоваться (или не будут работать так же, как и у F #) с других языков. Они заменяются на сайте вызова как функция компилятора F #, который не поддерживается С# и другими языками CLR. Это значительное преимущество F # над этими другими языками.

Однако есть некоторые исключения. Можно написать встроенные функции F #, которые выполняют диспетчеризацию на основе типа времени выполнения, который затем можно использовать с С# и другими языками. Как правило, они не получат тот же ИЛ, если они используются с С#, как и у F # для определенных типов (конкретные обработчики для примитивных типов не будут обрабатываться). Вот почему (+) работает - вы можете видеть это в коде для оператора, где (+) вызывает AdditionDynamic<(^T),(^U),(^V)> x y. Обратите внимание, что (-) отсутствует версия отправленной версии и явно помечена как [<NoDynamicInvocation>], поэтому он не работает с С#.

Это фактически то же ограничение в С#, которое заставляло людей запрашивать такие вещи, как IArithmetic (* используя интернет-архив, так как это было скрытый в Connect) в течение многих лет. F # работает вокруг этого через статически разрешенные параметры типа, но это функция, специфичная для F #, и не будет работать с С# и другими языками. Обертка функции через F # не включает ее в С#.