2009-12-23 8 views
19

Angesichts der F # Funktion höherer Ordnung (eine Funktion in Parameter genommen wird):Anruf eine höhere Ordnung F # Funktion von C#

let ApplyOn2 (f:int->int) = f(2) 

und die C# Funktion

public static int Increment(int a) { return a++; } 

Wie kann ich ApplyOn2 mit Increment nennen als Parameter (von C#)? Beachten Sie, dass ApplyOn2 als Microsoft.FSharp.Core.FSharpFunc<int,int> exportiert wird, die nicht mit der Signatur Increment übereinstimmen.

Antwort

17

Wenn Sie eine freundlichere Interop Erfahrung zur Verfügung stellen wollen, sollten Sie die Art System.Func Delegierten mit direkt in F #:

let ApplyOn2 (f : System.Func<int, int>) = f.Invoke(2) 

Sie wäre in der Lage Ihre F # Funktion sehr leicht Aufruf C# gefällt das:

MyFSharpModule.ApplyOn2(Increment); // 3 

Es gibt ein Problem mit der Increment-Funktion, wie Sie es geschrieben haben. Sie benötigen die Präfixform des Inkrementoperators, damit Ihre Funktion das korrekte Ergebnis zurückgibt:

public static int Increment(int a) { return ++a; } 
-2

Nur Verweis auf die Assembly erstellen:

#r @"Path\To\Your\Library.dll" 
let ApplyOn2 (f:int->int) = f(2) 
ApplyOn2 Library.Class.Increment 
+0

Das Problem besteht nicht auf referenzierenden Baugruppen. Das Problem ist, dass ApplyOn2 als Microsoft.FSharp.Core.FSharpFunc exportiert wird, die nicht mit Increment übereinstimmen. – sthiers

+1

Ich habe es versucht und es funktioniert: > ClassLibrary1.Class1.Increment ;; Binding-Sitzung zu 'J: \ Projects \ ClassLibrary1 \ ClassLibrary1 \ bin \ Debug \ ClassLibrary1.dll' ... val es: int -> int = > lassen ApplyOn2 (f: int-> int) = f (2) ;; val ApplyOn2: (int -> int) -> int > ApplyOn2 ClassLibrary1.Class1.Increment ;; val it: int = 2 – ssp

+2

@ssp: Dies ist ein Beispiel für den Aufruf von C# von F #. F # ist viel verzeihender über die Konvertierung von Funktionen und Delegaten, wie Sie bemerken, aber die Frage ist, F # von C# anzurufen. –

29

Um eine FSharpFunc aus der äquivalenten C# Funktion Gebrauch zu erhalten:

Func<int,int> cs_func = (i) => ++i; 
var fsharp_func = Microsoft.FSharp.Core.FSharpFunc<int,int>.FromConverter(
    new Converter<int,int>(cs_func)); 

Um eine C# Funktion aus dem Äquivalent FSharpFunc zu erhalten, verwenden

var cs_func = Microsoft.FSharp.Core.FSharpFunc<int,int>.ToConverter(fsharp_func); 
int i = cs_func(2); 

In diesem speziellen Fall könnte Ihr Code wie folgt aussehen:

Func<int, int> cs_func = (int i) => ++i; 
int result = ApplyOn22(Microsoft.FSharp.Core.FSharpFunc<int, int>.FromConverter(
      new Converter<int, int>(cs_func)));