2009-12-23 17 views
19

Given funkcja F # wyższego rzędu (biorąc funkcję w parametrze):Zadzwoń wyższego rzędu F # funkcji z C#

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

a funkcja C#

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

Jak mogę zadzwonić ApplyOn2 z Increment jako parametr (z C#)? Pamiętaj, że ApplyOn2 jest eksportowany jako Microsoft.FSharp.Core.FSharpFunc<int,int>, który nie jest zgodny z podpisem Increment.

Odpowiedz

17

Jeśli chcesz, aby zapewnić bardziej przyjazny doświadczenie współdziałania, należy rozważyć użycie System.Func typ delegata bezpośrednio w F #:

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

Byłbyś w stanie połączyć się z F # funkcję bardzo łatwo w C# jak to:

MyFSharpModule.ApplyOn2(Increment); // 3 

Istnieje jednak problem z funkcją Increment, jak już ją napisałeś. Potrzebujesz funkcji prefiksu operatora inkrementacji, aby funkcja zwróciła poprawny wynik:

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

Wystarczy utworzyć odniesienie do montażu:

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

Problem nie dotyczy zestawów referencyjnych. Problem polega na tym, że ApplyOn2 jest eksportowany jako Microsoft.FSharp.Core.FSharpFunc , które nie są zgodne z Inkrementacją. – sthiers

+1

Próbowałem go i działa: > ClassLibrary1.Class1.Increment ;; Sesja powiązania z 'J: \ Projects \ ClassLibrary1 \ ClassLibrary1 \ bin \ Debug \ ClassLibrary1.dll "... val it: int -> int = > let ApplyOn2 (f: int-> int) = f (2) ;; val ApplyOn2: (int -> int) -> int > ApplyOn2 ClassLibrary1.Class1.Increment ;; val it: int = 2 – ssp

+2

@ ssp: To jest przykład wywoływania C# z F #. F # jest znacznie bardziej wyrozumiały dla funkcji i delegowania konwersji typów, ale zwracasz uwagę na to, że wywołujesz F # z C#. –

29

Aby uzyskać FSharpFunc od równoważnej użyciu C# funkcji:

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

dostać funkcję C# od równoważnej FSharpFunc użyć

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

W tym konkretnym przypadku Twój kod może wyglądać następująco:

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