2011-08-20 11 views
6

Se scrivo qualcosa come il codice qui sotto,Perché gli eventi con accessori personalizzati non possono essere attivati ​​direttamente come fanno quelli predefiniti?

class MainClass 
{ 
    static EventHandler _myEvent= delegate{}; 
    static event EventHandler MyEvent 
    { 
     add{_myEvent += value;} 
     remove{_myEvent -= value;} 
    } 

    public static void Main (string[] args) 
    { 
     MyEvent(null,EventArgs.Empty); 
    } 
} 

il compilatore si lamenta: CS0079 Errore: L'evento MainClass.MyEvent' can only appear on the left hand side of + = 'o `- =' operatore.

Perché qualcosa di così strano come questo esiste? Se non posso lanciare un evento direttamente, perché dovrei usare una cosa del genere in primo luogo? È un bug (sto usando mono) o un design delicato e deliberato? Qualcuno potrebbe per favore insegnarmi la logica dietro a questo? Grazie in anticipo.

risposta

2

È possibile accedere solo a un evento nella classe di dichiarazione. Dietro le quinte, .NET crea variabili di istanza private per contenere il delegato.

Il compilatore sta effettivamente creando un evento pubblico e un campo privato. È possibile accedere al campo direttamente dalla stessa classe o classi nidificate. Dalle classi esterne, ti sarà consentito solo iscriversi/annullare l'iscrizione.

Grandi informazioni da Jon Skeet sono disponibili here sul perché questo sia e come funzioni.

+0

Questo non è il problema qui. Il tentativo di accedere all'evento _è_ dall'interno della classe dichiarante ... –

+0

@Nick: No, questo è assolutamente dire cosa sta succedendo: per un evento di tipo campo una chiamata che sembra invocare l'evento sta effettivamente invocando tramite il campo . Quindi prendi quella conoscenza e applicala all'evento personalizzato - invocando * quello * anche attraverso il campo di supporto. –

+0

@Jon: Concordo sul fatto che è possibile lavorare all'indietro da come vengono implementati eventi di tipo field per comprendere l'errore CS0079. Se la risposta fosse concentrata su questo, sarebbe stato +1 e fatto da me. Tuttavia, la risposta si concentra sull'accessibilità privata del campo, e questo è oltre il punto. –

2

È necessario richiamare il delegato di supporto dichiarato manualmente per aumentare l'evento: sostituire MyEvent(null, EventArgs.Empty) con _myEvent(null, EventArgs.Empty). Se ci pensate, l'aggiunta/rimozione personalizzata potrebbe memorizzare i delegati ovunque, ed è per questo che non potete recuperarli e invocarli nel modo in cui li avete scritti ...

+0

: Ma, cosa succede se voglio derivare la classe e non voglio esporre il campo delegato sottostante alla sottoclasse? Sarà un disastro, vero? Ho appena osservato che le sottoclassi non sono autorizzate a lanciare gli eventi della loro classe base. Non è un progetto debole? Gli eventi sono impiegati per impedire agli estranei di fare confusione con esso. Ma perché gli addetti ai lavori sono anche soggetti a restrizioni? – Need4Steed

+0

Lo schema consigliato è quello di fornire un metodo virtuale protetto che solleva l'evento: http://msdn.microsoft.com/en-us/library/ms229011.aspx. –

+1

Grazie per il tuo collegamento. Tuttavia, continuo a pensare che il progetto di non permettere di sparare sia piuttosto zoppo. Gli eventi possono essere virtuali ed essere sovrascritti da sottoclassi, ma per licenziarli, dobbiamo ricorrere ad alcuni metodi virtuali helper, com'è che non è zoppo? – Need4Steed

Problemi correlati