2011-12-09 9 views
5

Ho giocato con delegati, eventi e metodi anonimi. In tal modo un punto è diventato molto chiaro.Registrazione di eventi all'interno di un costruttore?

Non semplificare il processo di registrazione di eventuali metodi di eventi o delegare funzioni nel costruttore?

I miei test mostrano che funziona e impedisce di doverli dichiarare dopo l'istanziazione (come il costruttore dell'oggetto lo fa per te).

In effetti, le prestazioni sono piuttosto buone. Ci sono degli svantaggi nell'usare la parola chiave "this" per riferirsi all'oggetto corrente durante la costruzione/istanziazione dell'oggetto?

Questo sembra avere molto senso per me dato che tutti gli eventi sarebbero stati cablati durante l'istanziazione.

Ci sono aree che potrebbero essere un problema?

Esempio:

//Constructor 
public SayHello() 
{ 
    _name = "Unnamed"; 
    _isUpdated = false; 

    // Register event handler via lambda (ananymous method shorthand) 
    this.NameChanged += (object sender, EventArgs e) => { Console.WriteLine(e.message)); }; 
} 

risposta

12

Ci sono un paio di potenziali problemi con questo approccio. In primo luogo, dal lato più generale, di solito si dovrebbe preferire l'uso delle sovrascritture del metodo rispetto all'abbonamento agli eventi auto-pubblicati per ragioni di prestazioni. Ovviamente, questo non è possibile se l'evento è esposto da una classe basata esternamente che espone un evento senza un corrispondente metodo sovrascrivibile. Tuttavia, la sottoscrizione agli eventi auto-pubblicati dovrebbe essere un approccio di ultima istanza, non un approccio predefinito.

Il secondo potenziale problema è più grave, ma ha a che fare con ciò che fa il codice attivato dall'evento, non quale oggetto espone l'evento. Ad esempio, si consideri il seguente costruttore:

public Foo(Bar bar) 
{ 
    bar.SomeEvent += (s, e) => this.DoSomething(); 
} 

Se barre incendi SomeEvent su un altro thread, il metodo DoSomething del l'istanza di Foo potrebbe essere chiamato prima che l'istanza è stato completamente inizializzato. Questo è un problema abbastanza ben documentato nello spazio Java (si veda, ad esempio, http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html), ma la copertura è molto più rada per C# /. NET. http://www.bluebytesoftware.com/blog/2010/06/27/OnPartiallyconstructedObjects.aspx fornisce una copertura dettagliata per .NET, ma potrebbe essere più di quello che volevi sapere ...

+0

Nicole, punti eccellenti. Questo e 'esattamente quello che stavo cercando. Il mio istinto mi stava dicendo che la semplificazione aggiunta potrebbe essere problematica (quindi il post). Nel test le cose potrebbero andare bene, ma in produzione la legge di Murphy sarà in vigore ... probabilisticamente, tutto ciò che può accadere darà abbastanza tempo. Detto questo, se l'app in questione è multithreading come si afferma (ad esempio un servizio o un portale Web), la contesa razziale si verificherà a un certo punto nel tempo. Grazie. – Qubits

1

non credo che ci siano problemi. Spetta a te farlo in quel modo. È possibile utilizzare l'oggetto stesso nel suo costruttore. Funzionerebbe anche, se omettete this.

+0

Questo è quello che pensavo. Trovo molto "non" di dover dichiarare gli eventi sul lato client (dato che l'oggetto può istanziare tutto il codice). Detto questo, era solo alla ricerca di potenziali insidie ​​da considerare. Finora non ho incontrato nessuno ... tranne l'uso della memoria (preoccupazione minima solo quando l'evento non è rilevante). – Qubits

Problemi correlati