F # - О параметрах, передаваемых в методы C # - они кортежи или что?
Я много раз читал, что
Сборки, сгенерированные из F # или любого другого языка .NET (почти) неразличимы.
Затем я экспериментировал с F # и C # взаимодействием на .NET 4 (бета 2). Я создал новое решение и проект на C # со следующим классом:
public class MyClass {
public static int Add(int a, int b) { return a + b; }
}
Затем в проекте F # после ссылки на проект C # я попытался:
MyClsas.Add(4, 5) |> printfn "%d" // prints 9 (no kidding!)
Все идет нормально. Затем мне пришло в голову другое предложение, которое я читал много раз (возможно, в разных книгах):
При передаче аргументов в функции из других библиотек .NET вы используете синтаксис, такой как «.MethodName (parm1, parm2)», то есть параметры передаются как кортеж.
Добавьте это к тому, что я когда-то читал здесь на SO (но не смог найти его для ссылки), на вопрос, где OP пытался создать подобное использование[ 4, 5, 6 ]
(когда он имел в виду[4; 5; 6]
):
«Запятая - это оператор создания кортежа, для всего остального используйте точку с запятой».
Затем я изменил свой класс следующим образом:
public class MyClass {
public static int Add(int a, int b) { return a + b; }
public static int Add(Tuple<int, int> a) { return a.Item1; }
}
Теперь я попытался использовать его на F #:
MyClass.Add(4, 5) |> printf "%d" // prints ... (keep reading!)
Итак, сложив три цитаты выше, можно сделать вывод, что:
F # создаст кортеж, когда увидит(4, 5)
Тогда это вызовет перегрузкуAdd(Tuple<int, int>)
Так будет печатать 4К моему удивлению,напечатано 9, Разве это не интересно?
Что на самом деле здесь происходит? Приведенные выше цитаты и это практические наблюдения, похоже, противоречат друг другу. Можете ли вы обосновать «рассуждения» F # и, если возможно, указать на некоторые документы MSDN?
Спасибо!
РЕДАКТИРОВАТЬ(чтобы добавить больше информации (из ответа Блинди))
Если вы делаете:
MyClass.Add((4, 5)) |> printfn "%d" // prints 9
F # вызываетAdd(Tuple<int, int>)
перегрузки.
Однако, если вы создадите другой проект F # (таким образом, другую сборку) с этим:
namespace MyFSharpNamespace
type MyFShapClass = class
static member Add x y = x + y
end
Вы можете использовать его на C #, как это
public static void Main(string[] args) {
MyFSharpNamespace.MyFSharpClass.Add(4, 5);
}
Все идет нормально. Теперь, когда вы пытаетесь использовать его из F # (из другого проекта, другой сборки), вы должны сделать:
MyFSharpNamespace.MyFSharpClass.Add 4 5 |> printfn "%d"
Если вы передаете аргументы как(4, 5)
F # не будет компилироваться, потому чтоAdd
являетсяint -> int -> int
, и нет(int * int) -> int
.
Что случилось?!?