Devo usar eventos ou métodos abstratos?

5

Digamos que eu crie uma classe abstrata que gerencie algumas funcionalidades de rede para mim.

Eu quero ser notificado quando algo mudar. Por exemplo: OnConnect ou OnDisconnect .

Devo criar eventos para esses tipos de funções ou implementá-los como métodos abstratos?

public event OnConnectDelegate OnConnected;

ou:

protected abstract OnConnected(SomeClientObject connectedClient);

Eu criei as duas soluções e as duas funcionam conforme o esperado. Mas como sei, em geral, se devo expor a funcionalidade como um evento ou como um método abstrato? Existem situações em que devo claramente preferir uma sobre a outra? Os eventos suportam vários receptores, mas também é necessário removê-los quando o receptor não precisar mais recebê-los.

    
por riki 14.12.2014 / 09:32
fonte

2 respostas

3

Do artigo parcialmente desatualizado, mas ainda útil, do MSDN: " Quando usar delegados em vez de interfaces (guia de programação C #) ", algumas das regras básicas se destacam:

Use um delegado nas seguintes circunstâncias:

(3) The caller has no need to access other properties, methods, or interfaces on the object implementing the method.

Minha explicação:

O chamado (receptor de eventos) pode facilmente se apossar do chamador (remetente) porque pela prática recomendada o chamador passará por si próprio como o primeiro argumento (apropriadamente chamado de sender ) para o chamado.

No entanto, tentar navegar na direção inversa não é trivial. Um delegado pode ser qualquer coisa - um método estático, ou um lambda, ou basicamente qualquer coisa que não seja o objeto real que finalmente processa o evento. Assim, nem sempre é possível determinar qual é esse objeto real.

O último ponto pode ser trabalhado usando padrão de visitante . No entanto, isso adiciona muito código e isso faz com que qualquer discussão seja discutível.

Use uma interface nas seguintes circunstâncias:

(1) There is a group of related methods that may be called.

Eu adicionaria um pouco mais: "... e que esses métodos relacionados são encontrados no mesmo objeto ."

Esta pergunta foi feita muitas vezes. Basta procurar por "C #", "delegate", "interface" para obter muitos resultados. No entanto, leva tempo para examinar os inúmeros conselhos de todas as fontes para filtrar as relevantes, de acordo com sua situação.

    
por 14.12.2014 / 10:01
fonte
0

Eu sugiro fazer as duas coisas!

Esses métodos on * são o lugar ideal do qual para aumentar esses eventos. (Bem, deve ter algum mérito; é assim que a maioria, senão todas, o trabalho do .Net Windows Controls).

internal class Button2 : System.Windows.Forms.Button
   {
      protected overrides void onClick( EventArgs e )
      {
         if ( ! this.AmIgnoringTheUser() )
         } 
            // Ask the base Button control to raise the Click event 
            base.onClick( e ); 
         }
      }
   }

Se sua classe for declarada como "selada" (/ "notinheritable" / "final"), então o acima é provavelmente o motivo somente para ter os métodos on *. Você consumidores podem apenas anexar delegados de eventos.

Isso protege sua classe, em que as pessoas não podem se meter com suas entranhas, mas reduz sua usabilidade se, digamos, um controle visível. A Herança Visual torna o uso extenso desses métodos substituíveis em * pelo simples fato de que você não pode garantir a ordem na qual os delegados do evento são invocados. Você pode garantir a ordem em que os métodos on * são chamados.

    
por 15.12.2014 / 13:23
fonte