2014-12-04 11 views
7

Ho il seguente evento che i consumatori della mia classe possono collegare per ottenere messaggi diagnostici interni.CA1009: dichiarare correttamente i gestori di eventi?

public event EventHandler<string> OutputRaised; 

alzo l'evento con questa funzione

protected virtual void OnWriteText(string e) 
    { 
     var handle = this.OutputRaised; 
     if (handle != null) 
     { 
      var message = string.Format("({0}) : {1}", this.Port, e); 
      handle(this, message); 
     } 
    } 

Perché mi CA1009 Declare correttamente i gestori di eventi? Tutte le risposte che ho trovato non sembrano realmente applicabili al mio scenario ... Sto solo cercando di capire, non ho ancora una solida conoscenza degli eventi e dei delegati.

di riferimento sul CA1009: http://msdn.microsoft.com/en-us/library/ms182133.aspx

+0

[Gestori eventi C#] (http: //www.tutorialspoint. it/csharp/csharp_events.htm) || [EventHandler (TEventArgs)] (http://msdn.microsoft.com/en-us/library/db0etb8x%28v=vs.110%29.aspx) – MethodMan

risposta

12

Secondo 'regole', il tipo di parametro di EventHandler dovrebbe ereditare da EventArgs:

metodi del gestore evento prendere due parametri. Il primo è di tipo System.Object ed è denominato 'sender'. Questo è l'oggetto che ha generato l'evento . Il secondo parametro è di tipo System.EventArgs ed è denominato 'e'. Questi sono i dati associati all'evento. Per esempio , se l'evento viene generato ogni volta che un file viene aperto, i dati dell'evento contengono in genere il nome del file.

Nel tuo caso, che potrebbe essere qualcosa di simile:

public class StringEventArgs : EventArgs 
{ 
    public string Message {get;private set;} 

    public StringEventArgs (string message) 
    { 
     this.Message = message; 
    } 

} 

e la tua eventhandler:

public event EventHandler<StringEventArgs> OutputRaised; 

Quando si aumenta l'evento, si dovrebbe offcourse creare un'istanza dei StringEventArgs classe:

protected virtual void OnWriteText(string message) 
{ 
    var handle = this.OutputRaised; 
    if (handle != null) 
    { 
     var message = string.Format("({0}) : {1}", this.Port, e); 
     handle(this, new StringEventArgs(message)); 
    } 
} 

I Vorrei anche aggiungere che, in teoria, non c'è niente di sbagliato nel codice. Il compilatore non si lamenta e il tuo codice funzionerà. Il delegato EventHandler<T> non specifica che il parametro type debba ereditare da EventArgs. È FxCop che segnala che stai violando le "regole di progettazione" per la dichiarazione di un evento.

+0

OK, è quello che pensavo sarebbe stato il problema (dal 'string' non eredita 'EventArgs'. Grazie per aver confermato il mio sospetto, so che il codice "funziona", volevo solo sapere il motivo dell'errore in modo più dettagliato :) – Calvin

3

Gli eventi in .NET devono in genere contenere una derivata di EventArgs che il vostro non fa, quindi suppongo che questo sia il problema.

Definire i args evento da pubblicare per l'evento:

public class StringEventArgs : EventArgs 
{ 
    public StringEventArgs(string message) { this.Message = message; } 
    public string Message { get; private set; } 
} 

Cambia la tua dichiarazione di evento e il metodo di pubblicare:

public event EventHandler<StringEventArgs> OutputRaised; 

protected virtual void OnWriteText(string e) 
{ 
    var handle = this.OutputRaised; 
    if (handle != null) 
    { 
     var message = string.Format("({0}) : {1}", this.Port, e); 
     handle(this, new StringEventArgs(message)); 
    } 
} 
Problemi correlati