2013-03-03 7 views
6

So che gli eventi sono sempre associati ai delegati. Ma mi manca un uso fondamentale degli eventi e sto cercando di capirlo.Perché utilizzare gli eventi per ciò che posso fare con i delegati?

Ho creato un semplice programma di eventi, come di seguito, e funziona perfettamente.

namespace CompleteRef3._0 
{ 
delegate void someEventDelegate(); 

class EventTester 
{ 
    public event someEventDelegate someEvent; 

    public void doEvent() 
    { 
     if (someEvent != null) someEvent(); 
    } 

} 

class Program 
{ 
    static void EventHandler1() 
    { 
     Console.WriteLine("Event handler 1 called.."); 
    } 

    static void EventHandler2() 
    { 
     Console.WriteLine("Event handler 2 called.."); 
    } 
    static void EventHandler3() 
    { 
     Console.WriteLine("Event handler 3 called.."); 
    } 


    static void Main(string[] args) 
    { 
     EventTester evt = new EventTester(); 
     evt.someEvent += EventHandler1; 
     evt.someEvent += EventHandler2; 
     evt.someEvent += EventHandler3; 
     evt.doEvent(); 
     Console.ReadKey(); 

    } 
} 
} 

Ho sostituito la dichiarazione dell'evento con i delegati. Cioè ho sostituito la riga evento pubblico someEventDelegate someEvent; con someEventDelegate someEvent; sul programma sopra, e ottengo ancora lo stesso risultato. Ora, ero confuso sul motivo per cui abbiamo bisogno di usare Eventi, se può essere raggiunto solo dai delegati. Qual è il vero uso degli eventi?

Il programma modificato senza eventi è la seguente -

namespace CompleteRef3._0 
{ 
delegate void someEventDelegate(); 

class EventTester 
{ 
    someEventDelegate someEvent; 

    public void doEvent() 
    { 
     if (someEvent != null) someEvent(); 
    } 

} 

class Program 
{ 
    static void EventHandler1() 
    { 
     Console.WriteLine("Event handler 1 called.."); 
    } 

    static void EventHandler2() 
    { 
     Console.WriteLine("Event handler 2 called.."); 
    } 
    static void EventHandler3() 
    { 
     Console.WriteLine("Event handler 3 called.."); 
    } 


    static void Main(string[] args) 
    { 
     EventTester evt = new EventTester(); 
     evt.someEvent += EventHandler1; 
     evt.someEvent += EventHandler2; 
     evt.someEvent += EventHandler3; 
     evt.doEvent(); 
     Console.ReadKey(); 

    } 
} 
} 
+0

In breve, esponendo le interruzioni del delegato pubblico ** incapsulamento **. – Timeless

risposta

4

Certo, è possibile utilizzare i delegati, perché dietro le quinte di un evento è un costrutto che avvolge un delegato.

Tuttavia, la logica dell'utilizzo degli eventi anziché dei delegati è la stessa dell'utilizzo delle proprietà anziché dei campi - incapsulamento dei dati. È una cattiva pratica quella di esporre i campi (qualunque essi siano - campi primitivi o delegati) direttamente.

A proposito, hai perso una parola chiave public prima del tuo campo delegato per renderlo possibile nel secondo snippet.

Un altro "tra l'altro" con il secondo frammento: per i delegati è necessario utilizzare Delegate.Combine anziché "+ =".

+0

oh ya .. errore mio ho perso la parola chiave 'public' .. grazie per averlo preso per me. Lo modificherò .. Buone conoscenze per me usare 'Delegate.Combine'. Non lo sapevo prima! ... La tua risposta è buona, esattamente quello che pensavo - *** incapsulamento dei dati ***. –

+3

Buona risposta eccetto per l'ultima riga. ** Perché non dovremmo usare '+' e '+ =' e così via con i delegati? ** Sono stati messi nella lingua per rendere le cose belle. È ancora importante capire la differenza tra '+ =' con gli eventi (una sintassi per chiamare l'accessment di eventi 'add') e' + = 'con le variabili (qui' x + = y' è molto simile a 'x = x + y' dove '+' può essere una combinazione di delegati, concatenazione di stringhe, aggiunta aritmetica di qualche tipo o altri sovraccarichi). Un problema con 'Delegate.Combine' è che i tipi non sono controllati in qualsiasi momento della compilazione. Con '+' i tipi di tempo di compilazione sono controllati. –

7

Lo scopo principale degli eventi è quello di evitare che gli abbonati di interferire con l'altro. Se non si utilizzano gli eventi, è possibile:

sostituire altri abbonati riassegnando delegato (invece di utilizzare l'operatore + =), Cancella tutti gli abbonati (impostando delegato a null), Broadcast ad altri abbonati invocando la delegare.

Fonte: C# in un Nutshell

+3

+1. Assegnazione 'someEvent = new someEventDelegate (EventHandler2)' è il problema che si ha con l'uso diretto dei delegati. Un altro collegamento [Learning C# 3.0: padroneggia i fondamenti di C# 3.0 - Delegati ed eventi] (http://msdn.microsoft.com/en-us/library/orm-9780596521066-01-17.aspx) - questo capitolo particolare è disponibile su MSDN e entra nei dettagli su questo argomento. –

+0

grazie per il vostro riferimento .. –

5

Immagina di avere 3 abbonati che sono interessati al tuo evento.Hanno sottoscritto l'neppure come questo:

client 1

EventTester evt = new EventTester(); 
evt.someEvent += Client1Handler1; 
evt.someEvent += Cleint1Handler2; 

client 2

EventTester evt = new EventTester(); 
evt.someEvent += Client2Handler1; 
evt.someEvent += Client2Handler2; 

client 3

EventTester evt = new EventTester(); 
evt.someEvent += Client2Handler1; 
evt.someEvent += Client2Handler2; 

Ora immaginate un altro client fa questo:

EventTester = null; 

client 1, 2, e 3 non sarà sempre qualsiasi evento perché avete questa riga di codice:

if (someEvent != null) someEvent(); 

Non c'è niente di sbagliato con la riga di codice precedente, ma c'è il problema con l'utilizzo di delegati .

L'altro problema, come Alexei sottolineato è:

someEvent = new someEventDelegate(EventHandler2) 

Se si dispone di un event e uno dei client provato quanto sopra, non saranno ammessi e ottengono un errore di compilazione, in questo modo:

enter image description here

+0

Grazie. Hai spiegato molto bene l'uso dell'evento. :) –

Problemi correlati