2009-12-23 12 views
19

Dada la función F # de orden superior (teniendo una función en el parámetro):Llamar a un orden superior F # función de C#

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

y la función C#

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

Como llamar en ApplyOn2 con Increment como parámetro (de C#)? Tenga en cuenta que ApplyOn2 se exporta como Microsoft.FSharp.Core.FSharpFunc<int,int> que no coincide con la firma Increment.

Respuesta

17

Si desea proporcionar una experiencia de interoperabilidad más amigable, puede utilizar el tipo de delegado System.Func directamente en Fa #:

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

Usted sería capaz de llamar a su # función F muy fácilmente en C# como esto:

MyFSharpModule.ApplyOn2(Increment); // 3 

Hay un problema con la función de incremento como usted ha escrito sin embargo,. Necesita el formulario de prefijo del operador de incremento para que su función devuelva el resultado correcto:

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

Basta con crear referencia a su montaje:

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

El problema no está en hacer referencia a conjuntos. El problema es que ApplyOn2 se exporta como Microsoft.FSharp.Core.FSharpFunc que no coincide con Incremento. – sthiers

+1

Lo he intentado y funciona: > ClassLibrary1.Class1.Increment ;; Sesión de enlace a '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: Este es un ejemplo de invocación de C# desde F #. F # es mucho más indulgente con la función y delega la conversión de tipo, como usted señala, sin embargo, la pregunta es acerca de llamar a F # desde C#. –

29

Para tener una FSharpFunc del equivalente uso de C# función:

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

Para obtener una función de C# en la FSharpFunc equivalente, utilice

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

Por lo tanto, este caso particular, su código podría verse así:

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