DelegadosDelegates

Un tipo de delegado representa las referencias a métodos con una lista de parámetros determinada y un tipo de valor devuelto.A delegate type represents references to methods with a particular parameter list and return type. Los delegados permiten tratar métodos como entidades que se puedan asignar a variables y se puedan pasar como parámetros.Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. Los delegados son similares al concepto de punteros de función en otros lenguajes, pero a diferencia de los punteros de función, los delegados están orientados a objetos y presentan seguridad de tipos.Delegates are similar to the concept of function pointers found in some other languages, but unlike function pointers, delegates are object-oriented and type-safe.

En el siguiente ejemplo se declara y usa un tipo de delegado denominado Function.The following example declares and uses a delegate type named Function.

using System;
delegate double Function(double x);
class Multiplier
{
    double factor;
    public Multiplier(double factor) 
    {
        this.factor = factor;
    }
    public double Multiply(double x) 
    {
        return x * factor;
    }
}
class DelegateExample
{
    static double Square(double x) 
    {
        return x * x;
    }
    static double[] Apply(double[] a, Function f) 
    {
        double[] result = new double[a.Length];
        for (int i = 0; i < a.Length; i++) result[i] = f(a[i]);
        return result;
    }
    static void Main() 
    {
        double[] a = {0.0, 0.5, 1.0};
        double[] squares = Apply(a, Square);
        double[] sines = Apply(a, Math.Sin);
        Multiplier m = new Multiplier(2.0);
        double[] doubles =  Apply(a, m.Multiply);
    }
}

Una instancia del tipo de delegado Function puede hacer referencia a cualquier método que tome un argumento double y devuelva un valor double.An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. El método Apply aplica una función dada a los elementos de un argumento double[], y devuelve un valor double[] con los resultados.The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. En el método Main, Apply se usa para aplicar tres funciones diferentes a un valor double[].In the Main method, Apply is used to apply three different functions to a double[].

Un delegado puede hacer referencia a un método estático (como Square o Math.Sin en el ejemplo anterior) o un método de instancia (como m.Multiply en el ejemplo anterior).A delegate can reference either a static method (such as Square or Math.Sin in the previous example) or an instance method (such as m.Multiply in the previous example). Un delegado que hace referencia a un método de instancia también hace referencia a un objeto determinado y, cuando se invoca el método de instancia a través del delegado, ese objeto se convierte en this en la invocación.A delegate that references an instance method also references a particular object, and when the instance method is invoked through the delegate, that object becomes this in the invocation.

Los delegados también pueden crearse mediante funciones anónimas, que son "métodos insertados" que se crean sobre la marcha.Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. Las funciones anónimas pueden ver las variables locales de los métodos adyacentes.Anonymous functions can see the local variables of the surrounding methods. Por lo tanto, el ejemplo de multiplicador anterior puede escribirse más fácilmente sin utilizarse una clase de Multiplier:Thus, the multiplier example above can be written more easily without using a Multiplier class:

double[] doubles =  Apply(a, (double x) => x * 2.0);

Una propiedad interesante y útil de un delegado es que no sabe ni necesita conocer la clase del método al que hace referencia; lo único que importa es que el método al que se hace referencia tenga los mismos parámetros y el tipo de valor devuelto que el delegado.An interesting and useful property of a delegate is that it does not know or care about the class of the method it references; all that matters is that the referenced method has the same parameters and return type as the delegate.