FROM P239
1.委托概述
通过以下步骤来使用委托。
(1)声明一个委托类型。委托声明看上去和方法声明相似,只是没有实现块。
(2)使用该委托类型声明一个委托变量。
(3)创建委托类型的对象,把它赋值给委托变量。新的委托对象包括指向某个方法的引用,这个方法和第一步定义的签名和返回类型一致。
(4)你可以选择为委托对象增加其他方法。这些方法必须与第一步中定义的委托类型有相同的签名和返回类型。
(5)在代码中你可以像调用方法一样调用委托。在调用委托的时候,其包含的每一个方法都会被执行。
你可以把delegate看作一个包含有序方法列表的对象,这些方法具有相同的签名和返回类型。如下图所示
□方法的列表称为调用列表
□委托保存的方法可以来自任何类或结构,只要它们在下面两点匹配:
--委托的返回类型
--委托的签名(包括ref和out修饰符)
□调用列表中的方法可以是实例方法也可以是静态方法
□在调用委托时,会执行其调用列表中的所有方法
2.声明委托类型
1 delegate void MyDel (int x); 2 // 关键字 返回类型 委托类型名 签名
返回类型和签名指定了委托接收的方法的形式。
以上示例中的声明指定了MyDel类型的委托只会接受不返回值并且有单个int参数的方法。下图左边演示了委托类型,右边演示了委托对象。
委托类型声明在两个方面与方法声明不同。委托类型
□以delegate关键字开头
□没有方法主体
p.s.虽然委托类型声明看上去和方法的声明一样,但它不需要在类内部声明,因为它是类型声明。
3.创建委托对象
有两种创建委托对象的方式,第一种是使用带new运算符的对象创建表达式,如下面代码所示:
new运算符的操作数的组成如下:
□委托类型名
□一组圆括号,其中包含作为调用列表中第一个成员的方法的名字。方法可以是实例方法或静态方法。
1 delvar=new MyDel(myInstObj.MyM1); //创建委托并保存引用 实例方法 2 dVar=new MyDel(SClass.OtherM2); //创建委托并保存引用 静态方法 3 4 delvar=myInstObj.MyM1; //创建委托并保存引用 实例方法 5 dVar=SClass.OtherM2; //创建委托并保存引用 静态方法
还可以使用快捷语法,如上方代码后两行所示,它仅由方法说明符构成。这段代码和之前的代码是等价的,其能够工作是因为在方法名称和其相应的委托类型之间存在隐式转换。
除了为委托分配内存,创建委托对象还会把第一个方法放入委托的调用列表。
我们还可以使用初始化语法在同一条语句中创建变量和初始化对象。
4.给委托赋值
由于委托是引用类型,我们可以通过给它赋值来改变包含在委托变量中的引用。旧的委托对象会被垃圾回收器回收。
e.g.下面的代码设置并修改了delVar的值。
1 MyDel delVar; 2 delVar=myInstObj.MyM1; //创建委托对象并赋值 3 …… 4 delVar=SClass.OtherM2; //创建新的委托对象并赋值
5.组合委托
委托可以使用额外的运算符来“组合”。这个运算最后会创建一个新的委托,其调用列表连接了作为操作数的两个委托的调用列表副本。
e.g.如下代码创建了3个委托。第3个委托由前面2个委托组合而成。
1 MyDel delA=myInstObj.MyM1; 2 MyDel delB = SClass.OtherM2; 3 MyDel delC = delA + delB; //组合调用列表
尽管术语组合委托(combining delegate)让我们觉得好像操作数委托被修改了,其实它们并没有被修改。事实上,委托是恒定的。委托对象被创建后不能再被改变。