什么是委托
委托跟类一样,是用户自定义的类型。但类是表示数据的集合,委托是具有兼容返回类型和输入参数的方法或lambda表达式的集合。
如果你学过C++,那么可以把委托理解为指向函数的指针。但是,委托是类型安全和可靠的。
你可以把委托看做一个包含有【有序方法列表】的对象。这些方法具有相同的返回类型和签名(参数列表,包括ref和out修饰符)。
在调用委托时,会执行【有序方法列表】的所有方法。
委托的使用
声明委托类型
delegate <return type> <delegate-name> <parameter list>
e.g.
delegate void Mydel(int x);
1
2
3
创建委托对象
//变量声明
Mydel delVaer;
//使用带new运算符的对象创建表达式
delVar = new MyDel(Method1);
//快捷语法
delVar = Method1;
//当然也可以把创建变量初始化放在一起
Mydel delVar = new MyDel(Method1);
Mydel delVar = Method1;
**委托是引用类型**
1
2
3
4
5
6
7
8
9
10
11
12
组合委托
MyDel delA = Method1;
MyDel delB = Mythod2;
MyDel delC = delA + delB;
//delC的方法列表是delA和delB的方法列表的组合
1
2
3
4
为委托增加方法
Mydel del = Method1;
del += Method2;
del += Method3;
//委托是不可变的,所以实际发生的是创建了一个新委托,其调用列表是旧委托列表和方法的组合,然后这个新的委托赋值给del
1
2
3
4
从委托移除方法
del -= Method1;
//和增加方法一样,这里实际发生的是创建了一个新的委托
1
2
需要注意的是:
1. 删除的过程是从列表的最后开始搜索,并且移除第一个匹配的放法。
2. 试图删除委托中不存在的放法没有效果
3. 试图调用空委托会发生异常
4. 如果委托的调用列表为空,则委托是null
调用委托
可以像调用方法一样调用委托,委托的参数会用于方法列表的所有方法(除非有一个参数是输出参数)。
Mydel del = Method1;
del += Method2;
del += Method3;
del();//调用委托
1
2
3
4
调用带返回参数的委托
如果委托有返回值并且在调用列表中有一个以上的方法,会发生下面的情况:
调用列表最后一个方法的返回值就是委托的返回值
调用列表中其他方法的返回值都会被忽略
调用带引用参数的委托
匿名方法
delegate int Mydel(int x);
Mydel del = delegate (int x){return x+1;}
1
2
emmm,就是没有名字的方法。
语法:
delegate (Parameters){ ImplementationCode }
1
返回类型:匿名方法不会显式的声明返回类型,但其返回类型必须与对应的委托相一致
参数:必须与委托一致。需要注意的是,委托中的params关键字会被匿名方法忽略。
被捕获变量的生命周期会拓展。
delegate void Mydel();
static void Main(){
Mydel del;
{
int x = 5;//对匿名函数而言是外部变量
del = delegate(){
Console.WriteLine(x);//x被捕获
}
}
Console.WriteLine(x);//报错,未定义x
if (del != null){
del();//输出x的值
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Lamabda表达式
emmm,跟匿名函数一样是为了方便。其实,如果lambda表达式如果被先引进,就不会有匿名函数了。
Mydel del = delegate(int x) {return x+1;}
Mydel del = (int x)=>{return x+1;}
Mydel del = (x)=>{return x+1}//可以省略类型
Mydel del = x =>{return x+1}//如果只有一个参数可以省略()
Mydel del = x => x+1//若果语句块只包含一个返回语句,则可以把语句块替换为return后的表达式
1
2
3
4
5
lambda表达式要点:
1. lambda表达式参数列表中的参数必须在类型、数量和位置上与委托相匹配
2. 参数类型可以省略(隐式类型)。除非委托中有ref或者out参数—此时类型是必须的。
3. 如果只有一个参数并且是隐式的,则可以省略(),否则()是必须的
4. 如果没有参数,必须使用()
---------------------
作者:guojunxiu
来源:CSDN
原文:https://blog.csdn.net/guojunxiu/article/details/81010849
版权声明:本文为博主原创文章,转载请附上博文链接!