Metodi anonimi (Guida per programmatori C#)

Aggiornamento: novembre 2007

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, per cui un metodo anonimo può essere convertito in delegati con una varietà di 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 instance
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); };

A differenza delle variabili locali, la durata della variabile acquisita si estende finché i delegati che fanno riferimento ai metodi anonimi non diventano adatti per la Garbage Collection. Al momento della creazione del delegato viene acquisito un riferimento a n.

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()
    {
        // Instatiate 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

Concetti

Guida per programmatori C#

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#)

Altre risorse

Riferimenti per C#