2009-12-23 4 views
19

Compte tenu de la fonction d'ordre supérieur F # (en fonction du paramètre):Appel d'un ordre supérieur fonction F # de C#

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

et la fonction C#

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

Comment appeler ApplyOn2 avec Increment en tant que paramètre (de C#)? Notez que ApplyOn2 est exporté en tant que Microsoft.FSharp.Core.FSharpFunc<int,int>, ce qui ne correspond pas à la signature Increment.

Répondre

17

Si vous souhaitez offrir une expérience Interop plus convivial, pensez à utiliser le type de délégué System.Func directement en F #:

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

Vous seriez en mesure d'appeler votre fonction F # très facilement C# comme ceci:

MyFSharpModule.ApplyOn2(Increment); // 3 

Il existe cependant un problème avec la fonction Incrément telle que vous l'avez écrite. Vous avez besoin de la forme de préfixe de l'opérateur incrément pour que votre fonction pour retourner le résultat correct:

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

Il suffit de créer référence à votre Assemblée:

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

Le problème n'est pas sur des ensembles de référencement. Le problème est que ApplyOn2 est exporté en tant que Microsoft.FSharp.Core.FSharpFunc qui ne correspond pas à Increment. – sthiers

+1

Je l'ai essayé et cela fonctionne: > ClassLibrary1.Class1.Increment ;; session de liaison à 'J: \ Projects \ ClassLibrary1 \ ClassLibrary1 \ bin \ Debug \ ClassLibrary1.dll' ... val il: 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: Ceci est un exemple d'appel C# de F #. F # est beaucoup plus indulgent à propos de la conversion des fonctions et des types de délégués, comme vous le signalez, cependant, la question est d'appeler F # de C#. –

29

Pour obtenir un FSharpFunc de l'utilisation équivalente de la fonction C#:

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

Pour obtenir une fonction C# de l'équivalent FSharpFunc, utilisez

Donc, dans ce cas particulier, votre code pourrait ressembler à:
Func<int, int> cs_func = (int i) => ++i; 
int result = ApplyOn22(Microsoft.FSharp.Core.FSharpFunc<int, int>.FromConverter(
      new Converter<int, int>(cs_func))); 
Questions connexes