总结一下最近自己学习的委托,可能理解有错误,请各位大佬指正。
MSDN上给委托定义为:委托是一种定义方法签名的类型。 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联。 您可以通过委托实例调用方法。
这三句话的意思表明了委托是一种类型,但是一种很特殊的类型,包含参数,返回值,一般类前面会有一个class修饰,但是委托前面用delegate;
在实例化委托这个类型时需要与一个具体的方法相关联,而且这个方法的参数,返回值必须与委托定义的参数和返回值类型、个数一致
根据一个故事来吧..鸿门宴! 一位将军设了一场鸿门宴,喝酒的时候,
将军举左手,左边的部队杀出。将军举右手,右边的部队杀出。
用代码实现就是
一个将军的类:
public class Boss { // 1:左手 2:右手 public int Status { get; set; } }
左边的部队:
public class Left { public void Go() { Console.WriteLine("左部队,杀出!"); } }
右边的部队:
public class Right { public void Go() { Console.WriteLine("右部队,杀出!"); } }
然后在鸿门宴上,将军要喝酒了。
static void Main(string[] args) { Boss boss = new Boss() { Status = 1 }; if (boss.Status == 1)//举左手 { new Left().Go(); } else if (boss.Status == 2)//举右手 { new Right().Go(); } else//摔杯 { new Left().Go(); new Right().Go(); } Console.ReadKey(); }
是不是感觉代码很烂,而且扩展性不高,并且要是有好几场鸿门宴一起举行呢(虽然这是不可能的),要循环这一堆else if吗!
用委托试试吧!
将军设置的鸿门宴,将军发出委托,各部门接到委,等待将军举手部下执行委托.这个委托是有将军发出的所以:委托在将军这
//委托 public delegate void BossDelegate(int status); public class Boss { public BossDelegate action; // 1:左手 2:右手 public int Status { get; set; } }
然后左右两个部队收到将军的委托等待将军举手执行委托:
左部队
public class Left { Boss boss; public Left(Boss boss) { this.boss = boss; boss.action += Go; }
public void Go(int status) { if (status == 1) { Console.WriteLine("左部队,杀出!"); } } }
右部队
public class Rigth { Boss boss; public Rigth(Boss boss) { this.boss = boss; boss.action += Go; }
public void Go(int status) { if (status == 2) { Console.WriteLine("右部队,杀出!"); } } }
鸿门宴开始了:将军把委托分配下去,将军要举起左手
static void Main(string[] args) { Boss boss = new Boss() { Status = 1 }; Left left = new Left(boss); Rigth right = new Rigth(boss); boss.action(boss.Status);//执行委托 Console.ReadKey(); }
左部队,右部队接收到将军的委托,伺机而动,等待将军举杯执行委托
如果多场鸿门宴呢? 看一下
static void Main(string[] args) { List<Boss> bosss = new List<Boss>() { new Boss () { Status = 1 }, new Boss () { Status = 2 }, new Boss () { Status = 1 } }; Boss boss = new Boss(); Left left = new Left(boss); Rigth right = new Rigth(boss); foreach (var model in bosss) { boss.action(model.Status); } Console.ReadKey(); }
哎呦! 不错哦! 如果将军再加一个状态叫 摔杯 呢? 那是不是只需要修改左右部队的代码就可以了,而不用动其余代码了。
虽然增加了代码安全性,代码扩展性,代码的美观。但是还是有点太麻烦。
于是委托它就 进化了。。。匿名方法产生了
当我知道匿名方法的时候,大吃一惊,wc,这个直接调用一个方法有啥区别吗?
其实在使用时,这和普通方法没有区别,但是匿名方法可以在一定程度上减少系统开销
匿名方法是C#2.0的一个新特性,顾名思义,匿名方法就是没有名称的方法。
匿名方法最明显的好处就是可以降低另写一个方法的工作量;另外一个好处就是可以访问调用者的变量,降低传参数的复杂度。
Boss boss = new Boss();
boss.action += delegate(int status) { if (status == 1) { Console.WriteLine("左部队,杀出!"); } }; boss.action += delegate (int status) { if (status == 2) { Console.WriteLine("右部队,杀出!"); } };
C#引入匿名方法后,我们就不需要在单独写这些方法了,我们只需在匿名方法体内实现我们的业务逻辑即可!
通过使用匿名方法,由于您不必创建单独的方法,因此减少了实例化委托所需的编码系统开销。
但是呢~微软那帮人觉得上面那样搞代码还不够简洁,如是又产生了lambda表达式
于是他就二次进化了。。。
Lambda产生了
Lambda 表达式是一个匿名函数
Lambda简化了匿名委托的使用,减少开发中需要编写的代码量。
Lambda表达式的定义方式为:“([参数列表]) => 表达式”。运算符“=>”是一种与赋值运算“=”具有相同优先级的右结合运算符,在英语里读作:“goes to”。
Lambda表达式的本质是“匿名方法”,即当编译我们的程序代码时,“编译器”会自动将“Lambda表达式”转换为“匿名方法”。
Boss boss = new Boss(); boss.action += x => { if (x == 1) { Console.WriteLine("左部队,杀出!"); } }; boss.action += x => { if (x == 2) { Console.WriteLine("右部队,杀出!"); } };
哎呦不错哦~ 更加简介了,而且有了linq的影子了。
这样委托一步步进化到了最精简的Lambda。
这样一来代码就干净利索,而且容易扩展,并且美观度也提高了。
例子借鉴于:https://www.cnblogs.com/yinqixin/p/5056307.html