When designing interfaces member method's signatures are defined by their type’s signatures rather having their signatures inferred from the methods parameters. There are roughly 3 ways to define a methods signature and these lead to different compiled forms and different ways of calling these methods within F#. This below interface illustrates this:
type TestInterace =
interface
abstract DoSomethingCurryStyle : string -> string -> unit
// C# signature "FastFunc<string, object> DoSomethingCurryStyle(string param1);"
abstract DoSomethingTupleStyle : (string * string) -> unit
// C# signature "void DoSomethingTupleStyle(Tuple<string, string> tupple);"
abstract DoSomethingCSharpStyle : string * string -> unit
// C# signature "void DoSomethingCSharpStyle(string param1, string param2);"
end
The important thing to note is the only difference between tuple style and the C# is that the C# style has no parenthesis. The different way of calling these methods are illustrated below:
let TestTestInterface (thing : TestInterface ) =
thing.DoSomethingCurryStyle "hello" "hello";
let param = "hello", "hello" in
thing.DoSomethingTupleStyle param;
thing.DoSomethingCSharpStyle ("hello", "hello");
()
An interface can be implemented by a class as follows:
type TestInterface = interface
abstract DoSomethingElse : string * string -> unit
end
type TestClass() = class
interface TestInterface with
member x.DoSomethingElse(s,t) = printf "Hi %s and %s" s t
end
end
As of F# 1.9.2 much of this syntax optional (just to encourage you that you won't always have to write all those 'end' tokens...). You can then write just:
type TestInterface =
abstract DoSomethingElse : string * string -> unit
type TestClass() =
interface TestInterface with
member x.DoSomethingElse(s,t) = printf "Hi %s and %s" s t