F# Загадка: как вызвать перегрузку метода?

Первая часть: вызов F# из F#

Допустим, у нас есть следующий тип, определенный в F#:

type MyClass =
    static member Overload1 (x, y) = "Pim"
    static member Overload1 (x : System.Tuple<_, _>) = "Pam"
    static member Overload1 x = "Pum"

Теперь вы находитесь в другом модуле (в другом файле).

Как вы можете вызвать каждый из трех методов, показанных выше?

Вторая часть: вызов C# из F#

Теперь вы определяете класс в C#:

public class MyClass {
    public static string Overload1<a, b>(a x, b y) { return "Pim"; }
    public static string Overload1<a, b>(Tuple<a, b> x) { return "Pam"; }
    public static string Overload1<a>(a x) { return "Pum"; }
}

Как из кода F# вызвать каждый из трех методов, определенных в C#?


person Bruno Reis    schedule 09.01.2010    source источник
comment
О, спасибо за редактирование, Брайан. Кажется, я начинаю слишком привыкать к выводу типов!   -  person Bruno Reis    schedule 10.01.2010
comment
Что здесь интересно, так это то, что компиляторы F# и C# будут генерировать одну и ту же сигнатуру метода для методов Pam, однако для их вызова необходимо использовать разный (и хакерский) синтаксис!   -  person Bruno Reis    schedule 10.01.2010


Ответы (2)


Вот ответ на часть F #:

MyClass.Overload1(1,2)
MyClass.Overload1<_,_>(unbox (box (1,2)) : System.Tuple<int,int>)
MyClass.Overload1 1
person kvb    schedule 10.01.2010

Хм, мне неясно, можно ли назвать метод F# "Pam". Но вот остальные.

C#:

using System;
namespace CSharp
{
    public class MyClass
    {
        public static string Overload1<a, b>(a x, b y) { return "Pim"; }
        public static string Overload1<a, b>(Tuple<a, b> x) { return "Pam"; }
        public static string Overload1<a>(a x) { return "Pum"; }
    }
}

F#:

namespace FSharp

type MyClass =
    static member Overload1 (x, y) = "Pim"
    static member Overload1 (x : System.Tuple<_, _>) = "Pam"
    static member Overload1 x = "Pum"

namespace DoIt

module Examples =
    let CallFSharp() =
        printfn "%s" <| FSharp.MyClass.Overload1(1,2)   // Pim
        printfn "%s" <| FSharp.MyClass.Overload1((1,2)) // Pum!
        printfn "%s" <| FSharp.MyClass.Overload1(())    // Pum


    let CallCSharp() =
        printfn "%s" <| CSharp.MyClass.Overload1(1,2)             // Pim
        printfn "%s" <| CSharp.MyClass.Overload1<int,int>((1,2))  // Pam
        printfn "%s" <| CSharp.MyClass.Overload1(())              // Pum

    do
        CallFSharp()        
        CallCSharp()        

Конечно, на практике в IL редко можно увидеть методы, принимающие System.Tuple<...> объектов в качестве параметров.

person Brian    schedule 10.01.2010