As funções de retorno de chamada são uma parte importante da programação do Windows. Se você tem experiência em programação C ou C++, já usou retornos de chamada em muitas APIs do Windows. Depois de adicionar a palavra-chave AddressOf ao VB, desenvolvedores e desenvolvedores podem aproveitar APIs que antes eram restritas. As funções de retorno de chamada são, na verdade, ponteiros para chamadas de método, também conhecidas como ponteiros de função, que são um recurso de programação muito poderoso. O .NET implementa o conceito de ponteiros de função na forma de delegados. O que há de especial neles é que, diferentemente dos ponteiros de função C, os delegados .NET são seguros para o tipo. Isso mostra que o ponteiro de função em C é apenas um ponteiro para uma unidade de armazenamento. Não podemos dizer para onde esse ponteiro realmente aponta, muito menos os parâmetros e tipos de retorno. Conforme descrito neste capítulo, os delegados .NET operam como uma operação de tipo seguro. A seguir aprenderemos como o .NET usa delegados como forma de implementar eventos.
1. Confiança
Quando você deseja passar um método para outro método, você precisa usar um delegado. Para entender o que eles significam, dê uma olhada no seguinte código:
int i = int.Parse("99");
Estamos acostumados a passar dados como parâmetros para métodos, conforme mostrado no exemplo acima. Então, passar outro método para um método parece um pouco estranho. Às vezes a operação realizada por um método não é realizada nos dados, mas sim em outro método, que é mais complicado. Não sabemos qual é o segundo método em tempo de compilação. Esta informação só pode ser obtida em tempo de execução, então precisamos passar o segundo método como parâmetro para o primeiro método. :
1. Iniciar threads-----Em C#, você pode dizer ao computador para executar certas novas sequências de execução em paralelo. Esta sequência é chamada de thread. Use o método Start() em uma instância de System.Threading.Thread acumulado para iniciar a execução de um thread. Se quiser dizer ao computador para iniciar uma nova sequência de execução, você deve indicar onde a sequência será executada. O computador deve receber os detalhes do método para iniciar a execução, ou seja, o método Thread.Start() deve receber um parâmetro que defina o método a ser chamado pelo thread.
2. Classes gerais de biblioteca ------Existem muitas bibliotecas que contêm código para executar várias tarefas padrão. Essas bibliotecas geralmente são independentes. Desta forma, ao escrever a biblioteca, você saberá como realizar a tarefa. Mas às vezes as tarefas também contêm subtarefas. Somente o código do cliente que utiliza a biblioteca sabe como executar essas subtarefas. Por exemplo, escreva uma classe que pegue um array de objetos e os classifique em ordem crescente. No entanto, parte do processo de classificação envolve a reutilização de dois objetos no array, comparando-os para ver qual deles deve vir primeiro. Se você estivesse escrevendo uma classe que tivesse que ser capaz de classificar qualquer array de objetos, não poderia informar antecipadamente ao computador como os objetos deveriam ser comparados. O código cliente que lida com matrizes de objetos em uma classe também deve informar à classe como comparar os objetos a serem classificados. Em outras palavras, o código do cliente deve passar certos detalhes para a classe que tornará isso apropriado.
3. Eventos ------ geralmente notificam o código sobre quais eventos ocorreram. A programação GUI trata principalmente de lidar com eventos. Quando ocorre um evento, o tempo de execução precisa saber qual método deve ser executado. Isso requer passar o método que trata o tempo como parâmetro do delegado. Isso será discutido mais tarde.
Anteriormente estabelecemos a regra de que nomes de métodos às vezes são passados como argumentos para outros métodos. É necessário indicar a seguir como realizar este processo. A maneira mais simples é passar o nome do método como parâmetro. Por exemplo, no exemplo de thread anterior, suponha que um novo thread seja iniciado e que haja um método chamado EntryPoint(), que é onde o thread começa a ser executado.
void EntryPoint()
{
//faça tudo o que o novo thread precisa fazer
}
Você também pode usar o seguinte código para iniciar a execução de um novo thread:
Tópico NovoTópico = novo Tópico();
Thread.Start(EntryPoint); //ERRADO
Na verdade, esta é uma maneira muito simples, que é a usada em algumas linguagens como C e C++ (em C e C++, o parâmetro EntryPoint é um ponteiro de função).
Mas esta abordagem direta pode causar alguns problemas, como segurança de tipo. Ao fazer programação orientada a objetos, os métodos raramente existem isoladamente. Eles geralmente precisam ser associados a uma instância de classe antes de serem chamados. E este método não leva em conta esta questão. Portanto, o .NET Framework sintaticamente não permite essa abordagem direta. Se quiser passar um método, você deve encapsular os detalhes do método em um novo tipo de objeto, um delegado. Os delegados são apenas um tipo especial de objeto. O especial é que todos os objetos que definimos antes contêm dados, enquanto os delegados contêm apenas os detalhes dos métodos.
-