2011-11-15 14 views
6

Mi chiedo se faccio qualcosa di simile:C# eventi e metodi della classe

class A 
{ 
    public MethodA() 
    { 
    } 
    public MethodB() 
    { 
     ExternalObject.Click += this.MethodA; 
    } 
    public MethodC() 
    { 
     ExternalObject.Click -= this.MethodA; 
    } 
} 

A a = new A(); 
a.MethodB(); 
a.MethodC(); 

È questo andare a lavorare? Per "lavoro" intendo: il metodoA verrà annullato dall'evento ExternalObject.Click?

E altre questioni correlate:

cosa succede dietro le quinte quando un metodo di istanza viene usato al posto di un'istanza delegato? (come sopra)

Ciò causa la creazione implicita di un delegato?

In che modo l'operatore -= esegue il confronto tra i delegati, per riferimento o forse accade qualcosa di più sofisticato?

risposta

8

Sì, funzionerà come desiderato.

Il confronto non è per riferimento, è per valore, il che significa che è possibile annullare l'iscrizione di un diverso delegato, purché punti allo stesso metodo sullo stesso oggetto.

In altre parole, questo funzionerà bene:

var delegate1 = new ExternalObjectClickEventHandler(MethodA); 
var delegate2 = new ExternalObjectClickEventHandler(MethodA); 
ExternalObject.Click += delegate1; 
ExternalObject.Click -= delegate2; 

metodi anonimi sono diversi, però, non si può fare questo:

public MethodB() 
{ 
    ExternalObject.Click +=() => { return 10; }; 
} 

public MethodC() 
{ 
    ExternalObject.Click -=() => { return 10; }; 
} 

Mentre i metodi contengono lo stesso codice, sono considerate diverso, e quindi questo non funzionerà, ovvero, MethodC non annullerà la sottoscrizione del delegato aggiunto in MethodB.

Per risolvere questo problema, è necessario memorizzare il delegato tra le chiamate, in questo modo:

private ExternalObjectClickEventHandler _ClickEventHandler; 
public MethodB() 
{ 
    _ClickEventHandler =() => { return 10; }; 
    ExternalObject.Click += _ClickEventHandler; 
} 

public MethodC() 
{ 
    ExternalObject.Click -= _ClickEventHandler; 
} 

Ma il codice che avete mostrato, funzionerà.

quanto riguarda la tua domanda cosa succede dietro le quinte, è che le seguenti due righe di codice sono identici quando si tratta di codice generato:

ExternalObject.Click += MethodA; 
ExternalObject.Click += new ExternalObjectClickEventHandler(MethodA); 

Il secondo codice è quello generato dalla prima (supponendo il tipo di evento è come mostrato.)

La prima sintassi è stata (ad un certo punto) aggiunta come "zucchero sintattico" che viene tradotta dal compilatore come se fosse stata scritta la seconda sintassi. Nota che questo succede solo se il compilato può capire il tipo giusto al 100%. Ho visto alcuni casi (che non riesco a ricordare in questo momento) in cui dovevi usare la sintassi pienamente qualificata perché il compilatore non riusciva a capire cosa volevi dire. In particolare, i sovraccarichi di metodo e i generici possono confonderlo a questo proposito.

+0

Grazie per una risposta esauriente. – kubal5003

3

Sì, MethodA sarà annullato.

Circa la seconda domanda non sono sicuro al 100%, ma penso che lo = this.MethodA si converta in un delegato in background.

+0

+1. 'this.MethodA' sarà convertito implicitamente in un delegato. – kol

Problemi correlati