2011-02-08 10 views
5

In tutto il libro .NET ho letto la linea guida per l'implementazione degli eventi spiega che è necessario sottoclasse EventArgs e utilizzare EventHandler. Ho cercato più informazioni su http://msdn.microsoft.com/en-us/library/ms229011.aspx, e dice "Usa System.EventHandler invece di creare manualmente nuovi delegati da utilizzare come gestori di eventi". Capisco che ci siano ragioni importanti per utilizzare EventArgs, ma la mia domanda non è "Devo farlo in questo modo?", Ma "Posso farlo in questo modo?".Esiste un'associazione speciale tra la classe EventArgs e la parola chiave evento?

C'è qualche ragione per cui non posso utilizzare un delegato generico invece di uno EventHandler con i miei eventi? Ad esempio, se voglio un mittente fortemente tipizzato (qualcun altro si infastidisce per quello object sender?).

Per spiegare cosa intendo meglio, c'è qualche ragione che il seguente non funzionerà?

public class IoC 
{ 
    public AbstractFactory GetAbstractFactory() 
    { 
     var factory = new AbstractFactory(); 
     factory.CreateObject +=()=>new object(); 
     return factory; 
    } 
} 
public class AbstractFactory 
{ 
    public event Func<object> CreateObject; 

    private object OnObjectCreated() 
    { 
     if(CreateObject == null) 
     { 
      throw new Exception("Not injected."); 
     } 
     return CreateObject(); 
    } 


    private object _injectedObject; 
    public object InjectedObject 
    { 
     get 
     { 
      if(_injectedObject == null) 
      { 
       _injectedObject = OnObjectCreated(); 
      } 
      return _injectedObject; 
     } 
    } 
} 
+0

Ho fatto esattamente questo per implementare qualcosa di simile a una collezione osservabile. – asawyer

+0

Thread correlato: http://stackoverflow.com/questions/4828212/should-eventhandler-always-be-used-for-events/4828233 – CodesInChaos

risposta

5

È solo convenzione e non è richiesto il linguaggio. È possibile utilizzare qualsiasi tipo di delegato come evento.

La firma standard EventHandler<T> ha alcuni vantaggi però:

  1. È possibile estendere il parametro EventArgs. Questo non funzionerebbe se tu avessi un parametro per ogni cosa che vuoi passare nell'handler di eventi.
  2. Un EventHandler che accetta la EventArgs classe base può iscriversi a qualsiasi evento in seguito alla convenzione
  3. È possibile aggiungere i metodi di estensione per EventHandler<T> che appaiono su tutti gli eventi.
  4. Il tipo di reso è void. Altri tipi di ritorno non hanno molto senso come eventhandlers.
  5. Stai seguendo la convenzione. Seguire la convenzione di solito è una buona idea, a meno che non si abbiano argomenti convincenti da non fare.
3

Tutta la documentazione di Microsoft riguarda la progettazione delle librerie di classi di base e/o delle linee guida generali di progettazione di framework. Puoi usare qualunque modello tu voglia.

Detto questo, se le persone consumano il codice, sarà più familiare a loro se si seguono i modelli utilizzati da Microsoft.

0

Per quanto ne so, EventHandler e EventArgs sono le migliori pratiche, ma non c'è nulla per impedirti di utilizzare delegati arbitrari in una dichiarazione di evento. La parola chiave evento ti offre la funzionalità speciale di essere in grado di + = e - = delegati nello spazio eventi, invece di avere semplicemente un campo o una proprietà del tipo delegato, che accetterà solo un singolo delegato (a meno che tu non componga più delegati te stesso).

Avvertenza: non sono sicuro di cosa succede ai delegati con valori di ritorno in uno spazio eventi. La mia ipotesi è che i valori di ritorno vengono scartati, dal momento che più delegati con valori di ritorno assegnati all'evento sarebbero difficili da gestire. Ciò richiederebbe comunque qualche sperimentazione.

+0

Viene restituito l'ultimo valore. Ma è altrettanto inutile. –

Problemi correlati