委托Delegates

委托类型表示对具有特定参数列表和返回类型的方法的引用。A delegate type represents references to methods with a particular parameter list and return type. 通过委托,可以将方法视为可分配给变量并可作为参数传递的实体。Delegates make it possible to treat methods as entities that can be assigned to variables and passed as parameters. 委托类似于其他一些语言中的函数指针概念,但与函数指针不同的是,委托不仅面向对象,还类型安全。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.

下面的示例声明并使用 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);
    }
}

Function 委托类型实例可以引用需要使用 double 自变量并返回 double 值的方法。An instance of the Function delegate type can reference any method that takes a double argument and returns a double value. Apply 方法将给定的函数应用于 double[] 的元素,从而返回包含结果的 double[]The Apply method applies a given Function to the elements of a double[], returning a double[] with the results. Main 方法中,Apply 用于向 double[] 应用三个不同的函数。In the Main method, Apply is used to apply three different functions to a double[].

委托可以引用静态方法(如上面示例中的 SquareMath.Sin)或实例方法(如上面示例中的 m.Multiply)。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). 引用实例方法的委托还会引用特定对象,通过委托调用实例方法时,该对象会变成调用中的 thisA 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.

还可以使用匿名函数创建委托,这些函数是便捷创建的“内联方法”。Delegates can also be created using anonymous functions, which are "inline methods" that are created on the fly. 匿名函数可以查看周围方法的局部变量。Anonymous functions can see the local variables of the surrounding methods. 因此,可以更轻松地编写上面的乘数示例,而无需使用 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);

委托的一个有趣且有用的属性是,它不知道也不关心所引用的方法的类;只关心引用的方法是否具有与委托相同的参数和返回类型。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.