委托(delegate)

时间:2021-09-24 09:00:08

委托dekegate是一种动态调用方法的类型,与类、接口和数组相同,属于引用型,可以用来实现多路广播(MulticastDelegate)。

多路广播(MulticastDelegate):可以用"+""-"将多个委托对象合并、移除,可以使用"+="添加委托对象,"-="移除委托对象。

委托的特点:

1)委托类似于C++函数指针,但与指针不同的是,委托是完全面向对象的,是安全的数据类型;

2)委托允许将方法作为参数进行传递;

3)委托可用于定义回调方法;

4)委托可以把多个方法链接在一起。这样,在时间触发时,可同时启动多个时间处理程序。

委托的声明:

[访问修饰符] delegate 返回值类型 委托名([参数列表]);

public delegate int Calculate (int x, int y);

委托的实例化:

委托类型 委托变量名 = new 委托型构造函数 (委托要引用的方法名)

int Multiply (int x, int y)
{
return x * y;
} int Add(int x, int y)
{
return x + y;
} Calculate a = new Calculate(Multiply);
Calculate b = new Calculate(Add);
Calculate c = new Calculate(); c = a + b; //组合调用 c += new Calculate(Add); //添加委托对象 c -= a; //移除委托对象

其中,a,b为委托型对象。

由于实例化委托实际上是创建了一个对象,所以委托对象可以参与赋值运算,甚至作为方法参数进行传递。

使用委托:

Calculate calc = new Calculate(Add);

int result = calc(,);

这里calc相当于调用了Add方法。

使用匿名方法:

从C# 2.0开始,引入了匿名方法的概念,允许将代码块作为参数传递,避免单独定义方法。

委托类型 委托变量名 = delegate ([ 参数列表 ]){代码块};

using System;
delegate void D(int x); //声明委托 class C
{
public static void M1(int i)
{
Console.WriteLine("C.M1: " + i);
}
public static void M2(int i)
{
Console.WriteLine("C.M2: " + i);
}
public void M3(int i)
{
Console.WriteLine("C.M3: " + i);
}
}
class Test
{
static void Main()
{
D cd1 = new D( C.M1);
cd1(-); // call M1
Console.WriteLine(); D cd2 = null;
cd2 += new D( C.M2);
cd2(-); // call M2
Console.WriteLine(); D cd3 = cd1 + cd2;
cd3(); // call M1 then M2
Console.WriteLine(); cd3 += cd1;
cd3(); // call M1, M2, then M1
Console.WriteLine(); C c = new C(); //委托相同与否的判断条件:函数体是否相同
D cd4 = new D(c.M3);
cd3 += cd4;
cd3(); // call M1, M2, M1, then M3
Console.WriteLine(); cd3 -= cd1; // remove last M1
cd3(); // call M1, M2, then M3
Console.WriteLine(); cd3 -= cd4;
cd3(); // call M1 then M2
Console.WriteLine(); cd3 -= cd2;
cd3(); // call M1
Console.WriteLine(); cd3 -= cd2; // impossible removal is benign
cd3(); // call M1
Console.WriteLine(); cd3 -= cd1; // invocation list is empty
Console.WriteLine( cd3 == null ); // cd3(70); // System.NullReferenceException thrown
cd3 -= cd1; // impossible removal
Console.WriteLine( cd3 == null ); Console.ReadKey(true);
}
}

运行结果:

委托(delegate)