2012-01-31 11 views
6

Estoy intentando llamar a una función C# de f # donde la función C# toma una función (¿delegar?) Como parámetro y necesito que este argumento sea una función f #. Por ejemplo:Uso de delegados C# con funciones f #

Muestra C#

public static void function_1(double x, ref double y) 
{ 
    y = Math.Exp(x); 
} 

main() 
{ 
    state s; 
    call_func(s, function_1) 
} 

Así, call_func tiene un parámetro de tipo void fn(double, ref double)

en F # Traté:

let function_1 (x:double) (y:double byref) = 
    let y = 6.0 
    () 

let test = 
    let s = new state 
    let ret = call_func(s, function_1) 

pero me sale el error de que el f # function_1 tiene escriba double -> double byref -> unit cuando debería ser el tipo de delegado void fn(double, ref double).

¿Puedo emitir el tipo o algo así? ¿O hay un error?

Respuesta

9

Si desea crear un delegado de una función en C#, se puede utilizar el operador new y darle la función como un argumento:

let function_1 (x:double) (y:double) = 
    () 

Program.call_func(s, new Action<double, double>(function_1)) 

Pero, por some reason, si intenta usar el mismo aproximación con un delegado que contiene ref, se obtiene este error:

This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking 2 arguments.

por lo tanto, si usted sigue el consejo dado por el mensaje de error, puede escribir lo siguiente:

let function_1 (x:double) (y:double byref) = 
    y <- 6.0 

Program.call_func(s, new fn(fun x -> fun y -> function_1 x &y)) 

Esto compila y funciona como se esperaba.

Tenga en cuenta que para modificar el parámetro y, debe utilizar el operador <-. El uso de let y = 6.0 declara una variable completamente diferente que sombrea el parámetro.

+0

gracias por su ayuda, pero me aparece un error "El tipo 'fn' no está definido" para el nuevo argumento. – b1g3ar5

+0

'fn' es el tipo de delegado que la función espera. Tal vez te falta 'abrir' para el espacio de nombre en el que se encuentra. O puede llamarse algo más en tu código. O puede estar anidado en alguna clase (si ese es el caso, debe proporcionar el nombre junto con el nombre del tipo que contiene el delegado). – svick

+0

OK, entiendo, compila ahora. Si dejo fuera lo nuevo y lo compila también, ¿funcionaría eso? – b1g3ar5