3 Domanda: Come aggiungere un evento a una classe

domanda creata a Sat, Dec 1, 2018 12:00 AM

Dire che ho una classe chiamata Frog, sembra:

 
public class Frog
{
     public int Location { get; set; }
     public int JumpCount { get; set; }


     public void OnJump()
     {
         JumpCount++;
     }

}

Ho bisogno di aiuto con 2 cose:

  1. Voglio creare un evento chiamato Jump nella definizione della classe.
  2. Voglio creare un'istanza della classe Frog, e quindi creare un altro metodo che verrà chiamato quando salterà la Rana.
37
3 risposte                              3                         
 
public event EventHandler Jump;
public void OnJump()
{
    EventHandler handler = Jump;
    if (null != handler) handler(this, EventArgs.Empty);
}

poi

 
Frog frog = new Frog();
frog.Jump += new EventHandler(yourMethod);

private void yourMethod(object s, EventArgs e)
{
     Console.WriteLine("Frog has Jumped!");
}
    
57
2008-09-17 16: 44: 28Z
  1. grazie, anche se non vedo la necessità di questa riga "EventHandler handler = Jump;"
    2008-09-17 16: 50: 32Z
  2. questo è per evitare i dead handler .. in c # tra il momento in cui si controlla se un gestore è nullo e il tempo effettivo per richiamare il gestore il metodo avrebbe potuto essere rimosso. Quindi imposta un riferimento al punto in cui il gestore sta puntando, quindi cerca null su quel riferimento e invoca.
    2008-09-17 16: 53: 26Z
  3. Il primo snippet di codice sarebbe un oggetto statico globale? Altrimenti come fa a sapere cosa fa frog.Jump?
    2018-01-07 05: 37: 36Z

@CQ: Perché crei una copia locale Jump? Inoltre, puoi salvare il test successivo cambiando leggermente la dichiarazione dell'evento:

 
public event EventHandler Jump = delegate { };

public void OnJump()
{
    Jump(this, EventArgs.Empty);
}
    
1
2008-09-17 16: 50: 03Z
  1. La creazione della copia locale è una tecnica difensiva che impedisce a un exceptin di fare la comparsa se il gestore viene rimosso prima che abbia effettivamente possibilità di essere eseguito.
    2008-09-17 16: 52: 29Z
  2. Inoltre, se non si verifica il null, si otterrà una NullReferenceException se non ci sono gestori di eventi collegati all'evento quando si chiama Jump (this, EventArgs.Empty );
    2008-09-17 16: 54: 54Z
  3. Scott, stai assegnando un riferimento qui così questa "tecnica difensiva" è completamente inutile.
    2008-09-17 18: 23: 57Z
  4. Abe, il controllo per null è ridondante nel mio codice perché l'oggetto mai deve essere nullo (notare l'inizializzazione!)
    2008-09-17 18: 24: 52Z
  5. Non è inutile. La tecnica difensiva è per quando l'abbonato si annulla dall'evento tra il controllo nullo e la chiamata di funzione effettiva. Il tuo metodo crea una funzione inutile per ogni istanza della classe e chiama la funzione (con il sovraccarico necessario) ogni volta che l'evento si attiva.
    2008-09-18 01: 36: 15Z

Ecco un esempio di come utilizzare un normale EventHandler o un delegato personalizzato. Si noti che ?. viene utilizzato al posto di . per assicurare che se l'evento è nullo, fallirà in modo pulito (restituisce null)

 
public delegate void MyAwesomeEventHandler(int rawr);
public event MyAwesomeEventHandler AwesomeJump;

public event EventHandler Jump;

public void OnJump()
{
    AwesomeJump?.Invoke(42);
    Jump?.Invoke(this, EventArgs.Empty);
}

Si noti che l'evento stesso è nullo se non ci sono abbonati e che una volta invocato, l'evento è thread-safe. Quindi puoi anche assegnare un gestore vuoto predefinito per assicurare che l'evento non sia nullo. Si noti che questo è tecnicamente vulnerabile a qualcun altro wiping out di tutti gli eventi (utilizzando GetInvocationList), quindi utilizzare con cautela.

 
public event EventHandler Jump = delegate { };

public void OnJump()
{
    Jump(this, EventArgs.Empty);
}
    
1
2019-01-17 19: 17: 50Z
fonte posta Qui