2013-07-09 18 views
6

Ho letto il MSDN page sui delegati e sembrano semplici. Poi stavo guardando un codice che li usa e ho visto questo:Che cosa sta facendo questo metodo delegato?

public delegate void NoArguments(); 
public NoArguments Refresh = null; 
Refresh = new NoArguments(Reset); 

È quella terza riga che mi confonde. Come puoi un delegato a new delegato? Non è un oggetto, è un metodo, o piuttosto un delegato a un metodo. Secondo l'esempio sulla pagina MSDN, la creazione di un'istanza di un delegato avviene attraverso l'assegnazione semplice, non l'allocazione. Inoltre, perché il new del delegato assume un parametro, Reset, quando la dichiarazione dei delegati non accetta parametri?

risposta

1

Il delegato è "delegato a un metodo", ma anche un oggetto. Se si guarda NoArguments in qualsiasi decompilatore, si vedrà che in realtà è una classe che eredita da MulticastDelegate, con diversi metodi (Invoke, BeginInvoke, EndInvoke).

Per motivi storici, C# consente di creare istanze di tale classe utilizzando new NoArguments(method). Tuttavia nelle versioni moderne supporta anche una notazione di collegamento method che fa la stessa cosa. In entrambi i casi, si ha effettivamente un oggetto di tipo NoArguments in Refresh.

+0

Grazie per aver sottolineato che si tratta in effetti di un oggetto, non solo di un puntatore di funzione. – johnbakers

4

La parola chiave delegate indica che quanto segue è essenzialmente una firma di funzione, pertanto, Refresh diventa un po 'come un puntatore a una funzione che non accetta argomenti. Tuttavia, per assegnare qualcosa al puntatore Refresh, devi assegnargli una funzione a cui puntare. In questo caso, è la funzione Reset. Inoltre, la funzione Reset non deve accettare argomenti.

Inoltre, la sintassi:

Refresh = Reset; 

è anche valida, ed è solo zucchero sintattico per la sintassi più formale:

Refresh = new NoArguments(Reset); 

in entrambi i casi, si potrebbe quindi eseguite la funzione di reset chiamando Refresh:

Refresh(); 

si noti, tuttavia, che se si esegue Refresh() senza che sia stato assegnato, è possibile generare un'eccezione. Il modo per evitare questo sarebbe quello di controllare contro nullo:

if (Refresh != null) Refresh(); 
else { 
    // Refresh was never assigned 
} 
2

si potrebbe pensare delegato è come un tipo di funzione:

  • tipo Declare, la funzione restituisce vuoto e non hanno argomenti:

    variabile
    public delegate void NoArguments(); 
    
  • dichiarare di dato tipo e inizializzare esso:

    public NoArguments Refresh = null; 
    
  • Assegna un nuovo oggetto alla variabile. L'oggetto è in realtà una funzione Reset, che deve avere la stessa firma il delegato:

    Refresh = new NoArguments(Reset); 
    

UPDATE:

Si può rivedere il seguente link per maggiori informazioni: C# Delegates

Problemi correlati