Delegados no Common Type System
O Runtime oferece suporte a tipos de referência, chamados delegados, que servem a um propósito semelhante ao de ponteiros de função em C++.Diferentemente de ponteiros de função, delegados são seguros, verificáveis e do tipo seguro.Um tipo delegado pode representar qualquer método com uma assinatura compatível.Enquanto ponteiros de função podem representar somente funções estáticas, um delegado pode representar métodos estáticos e de instâncias.Delegados são usados para manipular eventos e funções callback no .NET Framework.
Observação: |
---|
O common linguagem tempo de execução não oferece suporte a serialização dos métodos global, portanto, delegados não podem ser usados para executar métodos global de outros domínios de aplicativo . |
Todos os representantes herdam de MulticastDelegate, que herda de Delegate.As linguagens C#, Visual Basic e C++ não permitem a herança desses tipos, ao invés de fornecerem palavras-chave para declarar delegados.
Além herdadas métodos, o Common linguagem tempo de execução fornece dois métodos especiais para tipos delegado: BeginInvoke e EndInvoke.Para obter mais informações sobre estes métodos, consulte Chamar métodos sincronizados de forma assíncrona.
Como representantes herdam de MulticastDelegate, um representante tem uma lista de chamada, que é uma lista dos métodos que o representante representa e que são executados quando o representante é chamado.Todos os métodos da lista recebem os argumentos fornecidos quando o delegado é chamado.
Observação: |
---|
O valor de retorno não está definido para um delegado que tenha mais de um método na sua lista de invocação, mesmo que o delegado tenha um tipo de retorno. |
Em muitos casos, como em métodos callback, um delegado representa apenas um método, e as únicas ações você precisa fazer são criar e invocar o delegado.
Para representantes que representam vários métodos, o .NET Framework fornece métodos das classes Delegate e MulticastDelegate de representantes para dar suporte a operações como adicionar um método à lista de chamada de um representante (o método Delegate.Combine), remover um método (o método Delegate.Remove), e obter a lista de chamada (o método Delegate.GetInvocationList).
Observação: |
---|
Não é necessário usar esses métodos para delegados manipuladores de eventos no C#, C++ e Visual Basic, já que essas linguagens fornecem sintaxe para adicionar e remover manipuladores de eventos. |
Representantes podem representar métodos static (Shared no Visual Basic) ou de instância.Normalmente quando um delegado representa um método de instância, a instância é acoplada ao delegado juntamente com o método.Por exemplo, um delegado manipulador de eventos pode ter três métodos de instância em sua lista de invocação, cada um com uma referência ao objeto ao qual o método pertence.
Na versão 2.0 do .NET Framework, também é possível criar e abrir um delegado para um método de instância.Um método de instância tem um parâmetro da instância implícito (representado por this em C# ou Me no Visual Basic), e ele pode ser representado por um tipo de representante que expõe este parâmetro oculto.Ou seja, o tipo delegado deve ter um parâmetro extra no início da sua lista formal de parâmetros, do mesmo tipo da classe a qual o método pertence.É oferecido suporte para o inverso desse cenário, para que seja possível vincular o primeiro argumento de um método estático.
Observação: |
---|
A criação de instância aberta e delegados estático fechados não é diretamente suportada Visual Basic, C++ ou translation from VPE for Csharp para construtores de delegado.Em vez disso, use uma das sobrecargas de método Delegate.CreateDelegate que especificam objetos MethodInfo, como Delegate.CreateDelegate(Type, Object, MethodInfo, Boolean). |
Na versão 2.0 do .NET Framework, os tipos de parâmetro e retorno de um delegado devem ser compatíveis com os tipos de parâmetro e retorno do método que o delegado representa; os tipos não precisam coincidir exatamente.
Observação: |
---|
Nas versões 1.0 e 1.1 do .NET Framework, os tipos devem coincidir exatamente. |
Um parâmetro de um delegado é compatível com o parâmetro correspondente de um método se o tipo do parâmetro do delegado for mais restritivo do que o tipo de parâmetro do método, porque isso garante que um argumento passado para o delegado possa ser passado com segurança para o método.
Da mesma forma, o tipo de retorno de um delegado é compatível com o tipo de retorno de um método se o tipo de retorno do método for mais restritivo do que o tipo de retorno do delegado, porque isso garante que o valor de retorno do método possa ser difundido com segurança para o tipo retorno do delegado.
Por exemplo, um representante com um parâmetro de tipo Hashtable e um tipo de retorno de Object pode representar um método com um parâmetro de tipo Object e um valor de retorno de tipo Hashtable.
Para mais informações e um exemplo de código, consulte Delegate.CreateDelegate(Type, Object, MethodInfo).
Cada representante tem um método BeginInvoke que permite a você chamar o representante assincronamente, e um método EndInvoke que limpa, posteriormente, os recursos.Esses métodos são gerados automaticamente para cada tipo delegado.Quando um representante é chamado usando o método BeginInvoke, o método que o representante representa é executado em um segmento pertencente ao ThreadPool.
Para mais informações e um exemplo de código, consulte Assíncrono de programação usando representantes.