Delegaty (F#)
Pełnomocnik reprezentuje wywołanie funkcji jako obiekt.F# zwykle należy używać wartości funkcji do reprezentowania funkcji jako pierwszą klasą wartości; Obiekty delegowane są jednak używane w.NET Framework i dlatego są wymagane, gdy współdziałać z interfejsów API, które oczekują je.Mogą również być używane podczas tworzenia biblioteki przeznaczony do użytku z innych.NET Framework języków.
type delegate-typename = delegate of type1 -> type2
Uwagi
W poprzednich składni type1 reprezentuje argumentu typu lub typów i type2 reprezentuje typ zwracany.Typy argumentów, które są reprezentowane przez type1 są automatycznie curried.Sugeruje to, dla tego typu, możesz użyć formularza krotka, jeśli argumenty funkcji docelowej są curried i krotka ujętego w nawiasy dla argumentów, które już są w postaci spoiny.Automatyczne currying usuwa zestaw nawiasów, pozostawiając argument krotka, który pasuje do metody docelowej.Odnoszą się do kodu przykład składni, które należy stosować w każdym przypadku.
Pełnomocnicy można dołączyć do wartości F# funkcji i statycznych lub metody instancji.Wartości funkcji F# mogą być przekazywane bezpośrednio jako argumenty do delegowania konstruktorów.Metody statyczne można skonstruować pełnomocnik przy użyciu nazwy klasy i metody.Dla metody instancji dostarcza się wystąpienie obiektu i metody w jeden argument.W obu przypadkach Członek dostępu operator (.) jest używany.
Invoke Metody na typ delegata wywołuje funkcję zhermetyzowanego.Ponadto delegatów mogą być przekazywane jako wartości funkcji, odwołując się do nazwy metody Invoke bez nawiasów.
Poniższy kod ilustruje składnię do tworzenia obiektów delegowanych, które reprezentują różne metody w klasie.W zależności od tego, czy metoda jest statyczna metoda lub metody instancji, i czy ma argumentów w postaci spoiny lub curried formularz Składnia deklarowania i przypisywanie delegata jest nieco inaczej.
type Test1() =
static member add(a : int, b : int) =
a + b
static member add2 (a : int) (b : int) =
a + b
member x.Add(a : int, b : int) =
a + b
member x.Add2 (a : int) (b : int) =
a + b
// Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int * int) -> int
// Delegate2 works with curried arguments.
type Delegate2 = delegate of int * int -> int
let InvokeDelegate1 (dlg : Delegate1) (a : int) (b: int) =
dlg.Invoke(a, b)
let InvokeDelegate2 (dlg : Delegate2) (a : int) (b: int) =
dlg.Invoke(a, b)
// For static methods, use the class name, the dot operator, and the
// name of the static method.
let del1 : Delegate1 = new Delegate1( Test1.add )
let del2 : Delegate2 = new Delegate2( Test1.add2 )
let testObject = Test1()
// For instance methods, use the instance value name, the dot operator, and the instance method name.
let del3 : Delegate1 = new Delegate1( testObject.Add )
let del4 : Delegate2 = new Delegate2( testObject.Add2 )
for (a, b) in [ (100, 200); (10, 20) ] do
printfn "%d + %d = %d" a b (InvokeDelegate1 del1 a b)
printfn "%d + %d = %d" a b (InvokeDelegate2 del2 a b)
printfn "%d + %d = %d" a b (InvokeDelegate1 del3 a b)
printfn "%d + %d = %d" a b (InvokeDelegate2 del4 a b)
Poniższy kod przedstawia kilka różnych sposobów, w jaki można pracować z delegatów.
type Delegate1 = delegate of int * char -> string
let replicate n c = String.replicate n (string c)
// An F# function value constructed from an unapplied let-bound function
let function1 = replicate
// A delegate object constructed from an F# function value
let delObject = new Delegate1(function1)
// An F# function value constructed from an unapplied .NET member
let functionValue = delObject.Invoke
List.map (fun c -> functionValue(5,c)) ['a'; 'b'; 'c']
|> List.iter (printfn "%s")
// Or if you want to get back the same curried signature
let replicate' n c = delObject.Invoke(n,c)
// You can pass a lambda expression as an argument to a function expecting a compatible delegate type
// System.Array.ConvertAll takes an array and a converter delegate that transforms an element from
// one type to another according to a specified function.
let stringArray = System.Array.ConvertAll([|'a';'b'|], fun c -> replicate' 3 c)
printfn "%A" stringArray
Dane wyjściowe z poprzedniego przykładu kod wygląda następująco:
aaaaa
bbbbb
ccccc
[|"aaa"; "bbb"|]