为委托添加方法
尽管通过上一节的内容我们知道了委托其实是不变的,不过C#提供了看上去可以为委托添
加方法的语法,即使用+:运算符。
例如,如下代码为委托的调用列表“添加”了两个方法。方法加在了调用列表的底部。
图14-7演示了结果。
MyDel delVar=inst.MyM1; //创建并初始化
delVar +=SCl.m3; //增加方法
delVar +=X.Act; //增加方法
当然,在使用+=运算符时,实际发生的是创建了一个新的委托,其调用列表是左边的委托加
上右边方法的组合。然后将这个新的委托赋值给de1Var。
从委托移除方法
我们还可以使用-=运算符从委托移除方法。如下代码演示了-=运算符的使用。图14-8演示
了这段代码应用在图14-7演示的委托上的结果。
delVar-=SCl.m3;
与为委托添加方法一样,其实是创建了一个新的委托新的委托是旧委托的副本一一只是没
有了已经被移除方法的引用。
如下是移除委托时需要记住的一些事项。
- 如果在调用列表中的方法有多个实例,一:运算符将从列表最后开始搜索,并且移除第一
个与方法匹配的实例。 - 试图删除委托中不存在的方法将无效。
- 试图调用空委托会抛出异常。可以通过将委托和null进行比较来判断委托的调用列表是
否为空。如果调用列表为空,则委托是null。
调用委托
关于调用委托需要知道的重要事项如下。
- 可以通过两种方式调用委托。一种是像调用方法一样调用委托,另一种是使用委托的
lnvoke方法。 - 如下面的代码块所示,可以将参数放在调用的圆括号内。用于调用委托的参数作用于调
用列表中的每个方法(除非其中一个参数是输出参数,稍后将介绍)。 - 如果一个方法在调用列表中多次出现,则在调用委托时,每次在列表中遇到该方法时都
会调用它。 - 调用时委托不能为空(null),否则将引发异常。可以使用if语句进行检查也可以使用
空条件运算符和lnvoke方法。
下面的代码演示了创建和使用delVar委托的过程,该委托以单个整数作为输入值。使用参
数调用委托会导致它使用相同的参数值去调用其调用列表中的每一个成员。下面的代码演示了调
用委托的两种方法一一像方法一样调用和使用lnvoke调用。图14-9解释了这个调用过程。
Mydel delVar=inst.MyM1;
delVar+=SCl.m3;
delVar+=X.Act;
...
if(delVar!=null)
{
delVar(55); //调用委托
}
delVar?Invoke(65); //使用Invoke和空条件运算符
委托的示例
如下代码定义并使用了没有参数和返回值的委托。有关代码的注意事项如下。
- Test类定义了两个打印函数。
- Main方法创建了委托的实例并增加了另外3个方法。
- 程序随后调用了委托,也就调用了它的方法。然而在调用委托之前,程序将进行检测以
确保它不是null。
//定义一个没有返回值和参数的委托类型
delegate void PrintFunction();
class Test
{
public void Print1()
{
Console.WriteLine("Print1 -- instance");
}
public static void Print2
{
Console.WriteLine("Print2 -- static");
}
}
class Program
{
static void Main()
{
Test t=new Test(); //创建一个测试类实例
PrintFunction pf; //创建一个空委托
pf=t.Print1; //实例化并初始化该委托
//给委托增加3个另外的方法
pf+=Test.Print2;
pf+=t.Print1;
pf+=Test.Print2;
//现在,委托含有4个方法
if(null!=pf) //确认委托有方法
pf();
else
Console.WriteLine("Delegate is empty");
}
}
这段代码产生了如下的输出:
Print1 -- instance
Print2 -- static
Print1 -- instance
Print2 -- static