Usar representantes (guia de programação C#) 

A delegado é um tipo que encapsula um método, semelhante a um ponteiro de função em C e C++ com segurança.Diferentemente dos ponteiros de função C, delegates são orientados a objetos, tipo seguros, e protegidos.O tipo de delegate é definido pelo nome do delegate.O exemplo a seguir declara um seemo delegate chamado Del que pode encapsular um método que recebe uma Sequência como um argumento e retorna Void:

public delegate void Del(string message);

Um objeto delegado normalmente é construído, fornecendo o nome do método que ao representante será quebrado ou com um Método anônimo.Depois que um representante é instanciado, uma chamada de método feita para o representante será passada pelo representante para esse método.Os parâmetros passados para o representante pelo chamador são passados para o método, e o valor de retorno, se houver, do método é retornado para o chamador pelo representante.Isso é conhecido como chamar o representante.Um representante instanciado pode ser chamado como se fosse o método disposto próprio.Por exemplo:

// Create a method for a delegate.
public static void DelegateMethod(string message)
{
    System.Console.WriteLine(message);
}
// Instantiate the delegate.
Del handler = DelegateMethod;

// Call the delegate.
handler("Hello World");

delegado tipos derivam o Delegate classe do .NET estrutura. Tipos delegados são selado— não pode ser derivados — e não é possível derivar classes personalizadas de Delegate. Como o representante instanciado é um objeto, ele pode ser passado como um parâmetro, ou atribuído a uma propriedade.Isso permite que um método para aceitar um representante como um parâmetro, e chamar o representante em algum momento posterior.Isso é conhecido como um retorno de chamada assíncrono, e é um método comum de notificar um chamador quando um processo longo foi concluído.Quando um representante é usado em dessa maneira, o código usando o representante não precisa qualquer conhecimento da implementação do método sendo usado.A funcionalidade é semelhante ao encapsulamento fornecer interfaces.Para obter mais informações, consulte Quando se usar Delegates em vez de interfaces.

Outro uso comum de retornos de chamada é definir um método de comparação personalizado e passar esse representante para um método de classificação.Ele permite que o código do chamador para se tornar parte do algoritmo de classificação.O método exemplo a seguir usa o Del tipo como um parâmetro:

public void MethodWithCallback(int param1, int param2, Del callback)
{
    callback("The number is: " + (param1 + param2).ToString());
}

Você pode então passar o representante criado acima para esse método:

MethodWithCallback(1, 2, handler);

e receber o seguinte saído para o console:

The number is: 3

Usando o delegado sistema autônomo uma abstração, MethodWithCallback não é necessário chamar diretamente o console — não precisa ser projetado com um console em mente. O que MethodWithCallback fazer é simplesmente preparar uma sequência e passar a sequência a outro método.Isso é especialmente eficiente uma vez que um método delegado pode usar qualquer número de parâmetros.

Quando um representante é construído para ajustar um método da instância, o representante referencia a instância e o método.Um representante possui sem conhecer o tipo de ocorrência exceto do método ele disposição, portanto, um representante pode referir-se a qualquer tipo de objeto, desde que não seja um método sobre esse objeto que corresponda a assinatura de representante.Quando um representante é construído para ajustar um método estático, ele somente referencia o método.Considere as seguintes declarações:

public class MethodClass
{
    public void Method1(string message) { }
    public void Method2(string message) { }
}

Juntamente com o estático DelegateMethod mostrado anteriormente, agora temos três métodos que podem ser delimitados por uma Del instância.

Mais de um método quando chamado pode chamar um representante.Isso é chamado para de difusão seletiva.Para adicionar um método adicional para lista do delegado de métodos — a lista de invocação — simplesmente requer a adição de dois delegados usando a adição ou operadores de atribuição de adição ('+' ou '+=').Por exemplo:

MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod;

//Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;

Neste momentoallMethodsDelegate contém três métodos em sua lista de invocação —Method1, Method2, e DelegateMethod. Os representantes de três originais, d1, d2, e d3, permanecem inalterados. Quando allMethodsDelegate é invocado, todos os três métodos são chamados na ordem.Se o representante usa parâmetros de referência, a referência é passada sequencialmente para cada um dos três métodos por sua vez, e quaisquer alterações por um método estão visíveis para o próximo método.Quando qualquer um dos métodos gera uma exceção que não é detectada no método, que exceção é passada para o chamador do representante e nenhum método subsequentes na lista da chamada são chamados.E / ou se o representante tiver um valor de retorno sem parâmetros, ele retorna o valor de retorno e parâmetros do método último chamada.Para remover um método da lista da chamada, use o decrement ou Diminuir operador de atribuição ('-' ou '-= ').Por exemplo:

//remove Method1
allMethodsDelegate -= d1;

// copy AllMethodsDelegate while removing d2
Del oneMethodDelegate = allMethodsDelegate - d2;

Porque os tipos de delegado é derivada de System.Delegate, os métodos e propriedades definidas por essa classe podem ser chamadas no delegado. Por exemplo, para localizar o número de métodos na lista da chamada Um do representante, você pode escrever:

int invocationCount = d1.GetInvocationList().GetLength(0);

Derivam de representantes com mais de um método em sua lista de invocação de MulticastDelegate, que é uma subclasse de System.Delegate. O código acima funciona em ambos os casos porque ambas as classes suportam GetInvocationList.

Representantes de difusão seletiva são usadas extensivamente em Manipulação eventos.Objetos de origem de evento enviar notificações de eventos para objetos que foram registrados para receber esse evento destinatário.Para registrar um evento, para o destinatário cria um método projetado para manipular o evento, e cria um representante para esse método e passa o representante para a fonte de eventos.A fonte chama o representante quando o evento ocorre.O representante chama o evento tratamento método no destinatário, entregar os dados do evento.O tipo Delegate para um determinado evento é definido pela fonte de eventos.Para obter mais informações, consulte Eventos (Guia de programação do C#).

Comparar representantes de dois tipos diferentes atribuídos no tempo compilação-resultará em um erro de compilação.Se as instâncias do delegado estaticamente forem do tipo System.Delegate, então a comparação é permitida, mas retornará false em time de execução. Por exemplo:

delegate void Delegate1();
delegate void Delegate2();

static void method(Delegate1 d, Delegate2 e, System.Delegate f)
{
    // Compile-time error.
    //Console.WriteLine(d == e);

    // OK at compile-time. False if the run-time type of f 
    // is not the same as that of d.
    System.Console.WriteLine(d == f);
}

Consulte também

Conceitos

Guia de Programação C#

Referência

Representantes (guia de programação C#)

Covariância e Contravariance em representantes (guia de programação C#)

Eventos (Guia de programação do C#)