Metodi anonimi (Guida per programmatori C#)
Nelle versioni di C# precedenti alla 2.0 era possibile dichiarare un delegato solo tramite metodi denominati. In C# 2.0 sono stati introdotti i metodi anonimi e in C# 3.0 e versioni successive le espressioni lambda sostituiscono i metodi anonimi come modalità preferita per scrivere il codice in linea. Le informazioni sui metodi anonimi presenti in questo argomento sono tuttavia valide anche per le espressioni lambda. Esiste solo un caso in cui un metodo anonimo fornisce funzionalità non presenti nelle espressioni lambda. I metodi anonimi consentono di omettere l'elenco di parametri. Questo significa che un metodo anonimo può essere convertito in delegati con diverse firme. Ciò non è possibile con le espressioni lambda. Per ulteriori informazioni specifiche sulle espressioni lambda, vedere Espressioni lambda (Guida per programmatori C#).
La creazione di metodi anonimi consente essenzialmente di passare un blocco di codice come parametro del delegato. Di seguito sono riportati due esempi:
// Create a handler for a click event.
button1.Click += delegate(System.Object o, System.EventArgs e)
{ System.Windows.Forms.MessageBox.Show("Click!"); };
// Create a delegate.
delegate void Del(int x);
// Instantiate the delegate using an anonymous method.
Del d = delegate(int k) { /* ... */ };
Utilizzando i metodi anonimi si riduce l'overhead della codifica nella creazione di istanze dei delegati, poiché non è necessario creare un metodo separato.
La specifica di un blocco di codice al posto di un delegato può risultare utile nelle situazioni in cui la necessità di creare un metodo potrebbe sembrare un overhead inutile, ad esempio quando viene avviato un nuovo thread. Questa classe crea un thread e contiene anche il codice eseguito dal thread, senza richiedere la creazione di un metodo aggiuntivo per il delegato.
void StartThread()
{
System.Threading.Thread t1 = new System.Threading.Thread
(delegate()
{
System.Console.Write("Hello, ");
System.Console.WriteLine("World!");
});
t1.Start();
}
Note
L'ambito dei parametri di un metodo anonimo è il blocco di metodi anonimi.
È errato inserire nel blocco di metodi anonimi un'istruzione di salto, ad esempio goto, break o continue se la destinazione è esterna al blocco. È altresì errato inserire all'esterno del blocco di metodi anonimi un'istruzione di salto, ad esempio goto, break o continue, se la destinazione è interna al blocco.
Le variabili e i parametri locali il cui ambito contiene una dichiarazione di metodo anonimo sono denominati variabili esterne del metodo anonimo. Nel segmento di codice riportato di seguito, ad esempio, n è una variabile esterna:
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };
Un riferimento alla variabile esterna n viene detto acquisiti quando viene creato il delegato. A differenza delle variabili locali, la durata di una variabile acquisita estende finché i delegati che fanno riferimento i metodi anonimi sono idonei per la procedura di garbage collection.
Un metodo anonimo non può accedere ai parametri ref o out di un ambito esterno.
All'interno del blocco di metodi anonimi non è possibile accedere a codice unsafe.
Non è possibile utilizzare metodi anonimi sul lato sinistro dell'operatore is.
Esempio
Nell'esempio seguente vengono illustrati i due modi disponibili per la creazione di un'istanza di un delegato:
Associazione del delegato con un metodo anonimo.
Associazione del delegato con un metodo denominato (DoWork).
In ogni caso quando il delegato viene richiamato verrà visualizzato un messaggio.
// Declare a delegate.
delegate void Printer(string s);
class TestClass
{
static void Main()
{
// Instantiate the delegate type using an anonymous method.
Printer p = delegate(string j)
{
System.Console.WriteLine(j);
};
// Results from the anonymous delegate call.
p("The delegate using the anonymous method is called.");
// The delegate instantiation using a named method "DoWork".
p = new Printer(TestClass.DoWork);
// Results from the old style delegate call.
p("The delegate using the named method is called.");
}
// The method associated with the named delegate.
static void DoWork(string k)
{
System.Console.WriteLine(k);
}
}
/* Output:
The delegate using the anonymous method is called.
The delegate using the named method is called.
*/
Vedere anche
Riferimenti
Delegati (Guida per programmatori C#)
Espressioni lambda (Guida per programmatori C#)
Codice unsafe e puntatori (Guida per programmatori C#)
Metodi (Guida per programmatori C#)
Delegati con metodi denominati e anonimi (Guida per programmatori C#)