2012-01-31 14 views
6

Próbuję wywołać funkcję C# z f #, gdzie funkcja C# przyjmuje funkcję (delegate?) Jako parametr i potrzebuję tego argumentu, aby był funkcją f #. Np:Używanie C# delegatów z funkcją f #

próbka C#

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

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

Więc call_func ma parametr typu void fn(double, ref double)

w F # ja próbowałem:

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) 

Ale pojawia się błąd, że f # function_1 ma wpisz double -> double byref -> unit, kiedy powinien to być typ delegata void fn(double, ref double).

Czy mogę rzucić typ lub coś w tym stylu? Czy jest jakiś błąd?

Odpowiedz

9

Jeśli chcesz utworzyć delegata z funkcji w F #, można użyć operatora new i nadać mu funkcję jako argument:

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

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

Ale dla some reason, jeśli starają się korzystać z tego samego podejście z delegatem, który zawiera ref, pojawi się ten błąd:

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.

Tak więc, jeśli przestrzegać zaleceń podanych w komunikacie o błędzie, można napisać następujące:

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)) 

Kompiluje i działa zgodnie z oczekiwaniami.

Należy pamiętać, że aby zmodyfikować parametr y, należy użyć operatora <-. Używanie let y = 6.0 deklaruje zupełnie inną zmienną, która cienia parametr.

+0

dziękuję za pomoc, ale pojawia się błąd "Typ" fn "nie jest zdefiniowany" dla nowego argumentu. – b1g3ar5

+0

'fn' jest typem delegata, którego funkcja oczekuje. Być może brakuje ci 'open' dla przestrzeni nazw, w której się znajduje. Lub może być nazwany czymś innym w twoim kodzie. Lub może być zagnieżdżony w jakiejś klasie (jeśli tak jest, powinieneś podać nazwę wraz z nazwą typu, który zawiera delegata). – svick

+0

OK, rozumiem - że kompiluje się teraz. Jeśli zrezygnuję z nowego, a fn też się skompiluje, czy to zadziała? – b1g3ar5