Pergunta

É sabido que você deve declarar eventos que tomam como parâmetros (object sender, EventArgs args). Por quê?

Foi útil?

Solução

Isso permite que o desenvolvedor consumir a capacidade de escrever um manipulador de eventos único para vários eventos, independentemente do remetente ou evento.

Editar: Por que você precisa de um padrão diferente? Você pode herdar EventArgs para fornecer qualquer quantidade de dados, e mudar o padrão só vai servir para confundir e frustrar qualquer desenvolvedor que é forçado a consumir este novo padrão.

Outras dicas

Na verdade este é discutível se este é ou não a melhor maneira prática de fazer eventos. Há a escola de pensamento que como eventos são destinados a separar dois segmentos de código, o fato de que o manipulador de eventos recebe o remetente, e tem que saber que tipo de lançar o remetente para, a fim de fazer qualquer coisa com ele é um anti- padrão.

Porque é um padrão bom para qualquer mecanismo de retorno de chamada, independentemente do idioma. Você quer saber quem enviou o evento (o remetente) e os dados que é pertinente para o evento (EventArgs).

Usando um único parâmetro, EventArgs, para os dados passados ??por um evento permite que você adicione dados para seu evento em futuras versões do seu software sem quebrar os consumidores existentes. Você simplesmente adicionar novos membros a uma classe EventArgs derivadas existente ou criar uma classe derivada com os novos membros.

Caso contrário, a consistência eo princípio da menor surpresa justificar o uso de EventArgs para passar dados.

Como remetente, em alguns casos (mas não todos) é útil saber que tipo enviou o evento. Usando um tipo diferente de objeto para o argumento remetente é demasiado restritiva:. Isso significaria que outros remetentes não poderia reutilizar a mesma assinatura evento

É um padrão bom para utilização, de que maneira o que sempre implementa o evento pode encontrar o que estava enviando-lo.

Também substituindo as EventArgs e passando dados através deles é o melhor método. Os EventArgs são uma classe de base. Se você olhar para vários controles que eventos de chamada, eles substituídos EventArgs que lhe dá mais informações sobre o evento.

Mesmo que você não precisa de argumentos para fazer o evento, se você não incluí-los com a primeira execução do quadro e deseja adicioná-los mais tarde, você quebra todas as implementações anteriores, e tem que re-escrever-lhes . Além disso, se você a criar um quadro e vai distribuir que se torna pior, porque todo mundo que usa o seu quadro precisará refatorar.

Chris Anderson diz no livro Framework Design Guidelines:

[T] o seu é apenas sobre um padrão. Por ter argumentos de evento embalados em uma classe que você ficar melhor versionamento semântica. Por ter um (sender, e) padrão comum é facilmente aprendido como a assinatura de todos os eventos.

Há situações em sua maioria envolvendo interoperabilidade que exigiria desvio deste padrão.

Parecia que essa era a maneira da Microsoft para evoluir o modelo de eventos ao longo do tempo. Parece também que eles também estão permitindo que uma outra maneira de fazê-lo com o "novo" delegado de Acção e é variações.

"Object sender" permite reutilizar um método para vários objetos quando o método do manipulador é suposto fazer algo com o objeto que disparou o evento, por exemplo 3 caixa de texto pode ter um único manipulador que irá repor o texto da caixa de texto de disparo .

A principal vantagem do EventArgs é que ele permite a informações evento refatorar sem a necessidade de assinaturas de mudança de todos os manipuladores em todos os projetos que estão inscritos para este tipo de evento.

Eu não posso pensar de uma maneira mais inteligente de lidar com eventos.

Às vezes você gostaria de forçar todos os seus consumidores de eventos para usar um parâmetro determinado evento, por exemplo, um evento de segurança que passa um parâmetro booleano, verdadeiro para o bem, falsas para o mal. Neste caso, você quer que seu consumidor para ser dolorosamente ciente do novo parâmetro, ou seja, você quer que seus consumidores para ser acoplado com esse parâmetro. Tome nota, os consumidores ainda estão dissociados da sua classe de evento de disparo, mas não do seu evento.

Eu suspeito que esse cenário se aplica a um grande número de casos e nesses casos o valor de EventArgs é muito reduzida.

O EventArgs classe por si só é inútil, uma vez que deve ser derivado de instanciar com qualquer conteúdo. Isto indicaria uma subclasse deve ser usado, e muitos já existem em .NET. Infelizmente, não consigo encontrar qualquer bons genéricos.

Vamos dizer que você quer delegar o registo de um evento genérico ... SEM escrever seu EventArgs própria subclasse. Pode parecer um exercício inútil, mas eu gosto de usar recursos existentes. Você pode passar o seu fio através do argumento de objeto, mas que vai contra a sua utilização pretendida. Tente encontrar uma boa referência de EventArgs subclasses no Google, e você vai chegar a seco. (Pelo menos eu fiz.)

ReSharper ajuda um pouco, uma vez que quando você digita "EventArgs" você verá uma lista de todas as classes (dentro do seu âmbito usando / importações) que contêm o "EventArgs" string. Lendo a lista que você verá muitas classes com nenhum membro da corda. Quando você começa a ControlEventArgs , você vê que a propriedade Text pode ser usado, mas com toda a sobrecarga de um controle do Windows. ConvertEventArgs pode ser útil, desde que você passe o tipo juntamente com os dados, mas isso ainda requer acoplamento forte que não é nem bem documentado nem tipo seguro inerentemente. DataReceivedEventArgs não tem nenhuma implementação. EntryWrittenEventArgs requer uma EventLogEntry com uma matriz de bytes ou StreamingContext para dados. ErrorEventArgs está mais próximo, com uma mensagem de exceção, se você não se importa chamar todos os seus log ErrorEvents eventos de exceção internamente. FileSystemEventArgs é provavelmente o mais próximo ainda, com duas cordas e uma necessários WatcherChangeTypes enum argumento que pode ser definido como 0, se você sabe o que está fazendo. LabelEditEventArgs usa um int e uma corda, se você não se importa exigir que o namespace Windows.Forms. RenamedEventArgs é semelhante ao FileSystemEventArgs com uma corda extra. Finalmente, ResolveEventArgs em System.Runtime.InteropServices passa uma única cadeia. Há outras bibliotecas, mas eu preso a alguns dos mais comuns. Assim, dependendo da implementação posso usar ErrorEventArgs , FileSystemEventArgs ou ResolveEventArgs para o registo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top