Delegados (F#)

Um delegado representa uma chamada de função como um objeto. Na F#, você normalmente deve usar valores de função para representar funções como valores de primeira classe; No entanto, os delegados são usados na.NET Framework e, portanto, são necessários quando você interoperar com APIs que esperava. Também pode ser usados quando a criação de bibliotecas destinados a uso dos outros.Idiomas do NET Framework.

type delegate-typename = delegate of type1 -> type2

Comentários

Na sintaxe anterior, type1 representa o tipo de argumento ou tipos e type2 representa o tipo de retorno. Os tipos de argumento são representados por type1 são automaticamente curried. Isso sugere que, para esse tipo de você usar um formulário de tupla, se os argumentos da função destino são curried e uma tupla entre parênteses para argumentos que já estão no formulário tupla. O currying automático remove um conjunto de parênteses, deixando um argumento de tupla que coincide com o método de destino. Consulte o exemplo de código para a sintaxe que você deve usar em cada caso.

Delegados podem ser anexados F# valores de função e estáticos ou métodos de instância. F# função valores podem ser passados diretamente como argumentos para delegar construtores. Para um método estático, você pode construir o delegado usando o nome da classe e o método. Para um método de instância, você pode fornecer a instância do objeto e o método em um argumento. Em ambos os casos, o membro do operador de acesso (.) é usado.

O Invoke método no tipo delegado chama a função encapsulado. Além disso, delegados podem ser passados como valores de função referenciando o nome do método Invoke sem parênteses.

O código a seguir mostra a sintaxe para criar delegados que representam vários métodos em uma classe. Dependendo se o método é um método estático ou um método de instância e se ele tem os argumentos a tupla ou no formulário curried, a sintaxe para declarar e atribuir o delegado é um pouco diferente.

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)

O código a seguir mostra algumas das maneiras diferentes, que você pode trabalhar com delegados.

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

A saída do exemplo de código anterior é o seguinte.

aaaaa
bbbbb
ccccc
[|"aaa"; "bbb"|]

Consulte também

Conceitos

Parâmetros e argumentos (F#)

Outros recursos

Referência de linguagem do F#

Eventos (F#)