Devo utilizzare eventi o metodi astratti?

5

Diciamo che creo una classe astratta che gestisca alcune funzionalità di rete per me.

Voglio essere in grado di ricevere una notifica quando qualcosa cambia. Ad esempio: OnConnect o OnDisconnect .

Devo creare eventi per questi tipi di funzioni o implementarle come metodi astratti?

public event OnConnectDelegate OnConnected;

o

protected abstract OnConnected(SomeClientObject connectedClient);

Ho prototipato entrambe le soluzioni ed entrambe funzionano come previsto. Ma come faccio a sapere in generale se dovrei esporre la funzionalità come un evento o come un metodo astratto? Ci sono situazioni in cui dovrei preferire chiaramente l'una rispetto all'altra? Gli eventi supportano più ricevitori ma uno deve anche rimuoverli quando il ricevitore non ha più bisogno di riceverli.

    
posta riki 14.12.2014 - 09:32
fonte

2 risposte

3

Dell'articolo parzialmente obsoleto ma ancora utile da MSDN: " Quando utilizzare i delegati anziché le interfacce (C # Programming Guide) ", alcune delle regole del pollice spiccano:

Utilizza un delegato nelle seguenti circostanze:

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

La mia spiegazione:

Il callee (ricevitore di eventi) può facilmente impossessarsi del chiamante (mittente) perché con la migliore pratica il chiamante passerà se stesso come primo argomento (giustamente chiamato sender ) al destinatario.

Tuttavia, cercare di navigare nella direzione opposta non è banale. Un delegato potrebbe essere qualsiasi cosa: un metodo statico, o un lambda, o fondamentalmente qualcosa di diverso dall'oggetto reale che alla fine elabora l'evento. Pertanto, non è sempre possibile determinare quale sia l'oggetto reale.

L'ultimo punto potrebbe essere risolto usando modello di visitatore . Tuttavia, questo aggiunge un sacco di codice e questo rende ogni discussione discutibile.

Utilizza un'interfaccia nelle seguenti circostanze:

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

Vorrei aggiungere un po 'di più: "... e questi metodi correlati sono da trovare sullo stesso oggetto ."

Questa domanda è stata posta molte volte. Cerca solo "C #", "delegato", "interfaccia" produrrà molti risultati. Tuttavia, ci vuole tempo per esaminare i numerosi consigli di tutte le fonti per vagliare quelli rilevanti in base alla situazione.

    
risposta data 14.12.2014 - 10:01
fonte
0

Suggerirei di fare entrambe le cose!

Quelli sui metodi * sono il luogo ideale da cui per aumentare quegli eventi. (Beh, deve avere qualche merito, questo è il modo in cui funziona la maggior parte, se non tutti, dei controlli Windows .Net).

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 la tua classe è dichiarata come "sealed" (/ "notinheritable" / "final"), allora la precedente è probabilmente la ragione only per avere i metodi on *. I consumatori possono solo allegare delegati di eventi.

Questo protegge la tua classe, in quanto la gente non può muck con le sue interiora, ma riduce la sua usabilità se è, per esempio, un controllo visibile. L'Ereditarietà visiva rende esteso l'uso di questi metodi sovrascrivibili su * per il semplice motivo che non è possibile garantire l'ordine in cui vengono richiamati i delegati dell'evento. puoi garantire l'ordine in cui i metodi on * sono richiamati.

    
risposta data 15.12.2014 - 13:23
fonte

Leggi altre domande sui tag