委托是一类相同函数(返回值类型与参数列表一致)的链表。什么是返回值类型与参数列表一致的函数?这个很容易理解。如以下代码所示:
-
void showName(string name)
-
{
-
}
-
void showTitle(string title)
-
{
-
}
上面说了委托是链表。然后你在声明委托的时候,要说明链表中函数的返回类型与参数列表,比如我声明返回类型为void,参数列表为string的委托。
-
delegate void func(string f);
-
//我声明的func与下面两个函数返回类型与参数列表一致
-
void showName(string name)
-
{
-
}
-
void showTitle(string title)
-
{
-
}
-
delegate int func2(int x, int y);
-
//我声明的func2与下面两个函数返回类型与参数列表一致
-
int plus(int x,int y){
-
return x + y;
-
}
-
int mult(int x, int y) {
-
return x * y;
-
}
上面提到很多“委托”这个词,其实后面还有省略的两个字“类型”。你声明委托是声明了一种类型。声明以后就可以把该类型当参数传入。
-
delegate void func();
-
void showName(func name)
-
{
-
}
以上func name并没有报错因为声明委托结束,代码中就有了func这个类型。既然有类型,那么我们就可以根据类型生成实例。比如
-
delegate void func();
-
func l;
我们定义了一个返回值为void,无参数的func类型的链表。然后声明了一个具体实例l。这里用l就是list的意思,帮助大家容易理解。然后就可以往链表里添加函数。使用符号“+=”
-
delegate void func(string f);
-
static func l;
-
static void showName(string name)
-
{
-
}
-
static void showTitle(string title)
-
{
-
}
-
static void Main(string[] args)
-
{
-
//这里两个函数要加static(静态的)不然需要你通过具体类来引用,委托同理。
-
l += showName;
-
l += showTitle;
-
}
通过以上操作,你就在函数链表l添加了showName与showTitle两个函数。这里很像长鞭炮,你把函数串联起来了。如果你调用l这个委托,就相当于点燃了引线,所有函数就会依次运行一遍。
-
delegate void func(string f);
-
static func l;
-
static void showName(string name)
-
{
-
Console.WriteLine("你先输出了名字,参数:"+name);
-
}
-
static void showTitle(string title)
-
{
-
Console.WriteLine("你又输出了主题,参数:"+title);
-
}
-
static void Main(string[] args)
-
{
-
l += showName;
-
l += showTitle;
-
l("一个参数");
-
Console.ReadKey();
-
}
当然你可以传入函数,在调用函数,效果一样。
-
delegate void func(string f);
-
static func l;
-
static void showName(string name)
-
{
-
Console.WriteLine("你先输出了名字,参数:"+name);
-
}
-
static void showTitle(string title)
-
{
-
Console.WriteLine("你又输出了主题,参数:"+title);
-
}
-
static void run(func l) {
-
l("一个参数");
-
}
-
static void Main(string[] args)
-
{
-
l += showName;
-
l += showTitle;
-
run(l);
-
Console.ReadKey();
-
}
链表模型(l的模型)
showName() | showTitle() |
如果使用=号将清空链表,使链表中只剩最后一个等号后的函数。也可以使用-=,来清除对应的函数。这里请大家自行测试。
具有返回值的委托类型,返回值默认是最后一个函数的返回值,就是最后添加的返回值。
-
delegate int func(int j,int k);
-
static func l;
-
static int plus(int x,int y){
-
return x + y;
-
}
-
static int mult(int x, int y) {
-
return x * y;
-
}
-
static void Main(string[] args)
-
{
-
l += plus;
-
l += mult;
-
Console.WriteLine(l(4,5));
-
Console.ReadKey();
-
}
运行以上返回值是20,结果是最后一个函数返回值。如何获取每个函数的返回值,这里写了一个示例:
-
delegate int func(int j,int k);
-
static func l;
-
static int plus(int x,int y){
-
return x + y;
-
}
-
static int mult(int x, int y) {
-
return x * y;
-
}
-
static void Main(string[] args)
-
{
-
l += plus;
-
l += mult;
-
foreach(Delegate i in l.GetInvocationList()){
-
func k=(func)i;
-
Console.WriteLine(k(4,5));
-
}
-
Console.ReadKey();
-
}
委托就讲到这里,重新概括一下就是
- 委托是一种类型
- 委托是一种类型与返回值相同函数的链表
- 委托使用+=,=,-=三个符号操作链表里的函数
- 调用委托就会依次调用委托链表里的所有函数
- 委托返回值默认是最后一个添加的函数返回值
关于事件(event)
事件是一种特殊的委托,事件需要与类结合起来理解。
首先明确关键字event在实例化委托时使用而非定义委托时使用。
委托定义与使用
-
delegate void func();
-
static func l;
注意关键字的位置,在实例化的时候使用event;
事件需要与类结合起来,定义事件的类才可以调用事件。
-
delegate void func();
-
class Program
-
{
-
static void Main(string[] args)
-
{
-
Person.l();//这里报错Person.l”只能出现在 += 或 -= 的左边(从类型“Person”中使用时除外)
-
Console.ReadKey();
-
}
-
}
-
class Person{
-
public static event func l;//这里定义事件
-
void Action() {
-
l();//这里没有报错因为这里在定义事件的类里。
-
}
-
}
之前讲过,委托就像是一串鞭炮。将函数链接与取消或者触发,可以自由使用。但是事件限定了只能由声明事件的类来触发。而链接函数的过程,可以看做一种通知。这里写一个黑人抬棺的例子帮助大家理解