Métodos anónimos (Guía de programación de C#)

En versiones de C# anteriores a la versión 2.0, la única manera de declarar un delegado era utilizar métodos con nombre. C# 2.0 introdujo los métodos anónimos, mientras que, en C# 3.0 y versiones posteriores, las expresiones lambda reemplazan a los métodos anónimos como la manera preferente de escribir código insertado. No obstante, la información sobre los métodos anónimos de este tema también se aplica a las expresiones lambda. Hay un caso en el que un método anónimo proporciona una funcionalidad que no se encuentra en las expresiones lambda. Los métodos anónimos permiten omitir la lista de parámetros. Esto significa que los métodos anónimos pueden convertirse en delegados con diversas firmas. Esto no es posible con expresiones lambda. Para obtener más información sobre las expresiones lambda, vea Expresiones lambda (Guía de programación de C#).

La creación de métodos anónimos es básicamente una forma de pasar un bloque de código como parámetro de delegado. A continuación se describen dos ejemplos de esto:

// 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) { /* ... */ };

Mediante los métodos anónimos, se reduce la sobrecarga de codificación a la hora de crear instancias de delegados, ya que no es necesario crear un método independiente.

Por ejemplo, especificar un bloque de código en vez de un delegado puede ser útil en el caso de que la creación de un método pueda suponer una sobrecarga innecesaria. Un buen ejemplo es cuando se inicia un nuevo subproceso. Esta clase crea un subproceso y también contiene el código que el subproceso ejecuta sin crear un método adicional para el delegado.

void StartThread()
{
    System.Threading.Thread t1 = new System.Threading.Thread
      (delegate()
            {
                System.Console.Write("Hello, ");
                System.Console.WriteLine("World!");
            });
    t1.Start();
}

Comentarios

El ámbito de los parámetros de un método anónimo es el bloque del método anónimo.

Es un error utilizar una instrucción de salto, como goto, break o continue, en un bloque de método anónimo si el destino está fuera del bloque. También es un error utilizar una instrucción de salto, como goto, break o continue, fuera de un bloque de método anónimo si el destino está dentro del bloque.

Las variables locales y los parámetros cuyo ámbito contiene una declaración de método anónimo se denominan variables externas del método anónimo. Por ejemplo, en el segmento de código siguiente, n es una variable externa:

int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

A diferencia de las variables locales, el período de duración de la variable capturada se extiende hasta que los delegados que hacen referencia a los métodos anónimos cumplan con los requisitos para la recolección de elementos no utilizados. En el momento en que se crea el delegado, se captura el valor de n.

Un método anónimo no puede tener acceso a los parámetros ref u out de un ámbito externo.

No se puede obtener acceso a código no seguro dentro del bloque de método anónimo.

No se permite el uso de métodos anónimos en el lado izquierdo del operador is.

Ejemplo

El ejemplo siguiente muestra las dos maneras de crear instancias de un delegado:

  • Asociar el delegado a un método anónimo.

  • Asociar el delegado a un método con nombre (DoWork).

En cada uno de los casos, se muestra un mensaje cuando se invoca al delegado.

// 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.
*/

Vea también

Referencia

Delegados (Guía de programación de C#)

Expresiones lambda (Guía de programación de C#)

Código no seguro y punteros (Guía de programación de C#)

Métodos (Guía de programación de C#)

Delegados con métodos con nombre y delegados con métodos anónimos (Guía de programación de C#)

Conceptos

Guía de programación de C#

Otros recursos

Referencia de C#