委托和事件(一)
委托、事件、Lambda表达式,下一个难关,准备开闯。
什么是委托?
委托是持有一个或多个方法的对象。所以,委托是可以执行的对象,当执行委托的时候,就是执行委托所持有的方法。
举个栗子
有主管和员工两个类,主管类里有个方法是扣钱,员工类里有个方法是偷懒,那么这个时候就可以创建一个委托,即员工一但偷懒,主管就执行扣钱。
比如员工类这么写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class Employee { private int salary; //员工薪水 private Manager theManager; //该员工的主管 //构造函数,初始化员工薪水和实际主管 public Employee(Manager manager) { theManager = manager; salary = 8000; } //薪水属性 public int Salary { get{ return salary; } set{ salary = value; } } //偷懒方法 public void PlayGame() { ConsoleWriteline("员工开始玩游戏了..."); theManager.RemoveMoney(this); } } |
下面是主管类:
1 2 3 4 5 6 7 8 9 10 11 | public class Manager { public void RemoveMoney(Employee employee) { ConsoleWriteline("开始扣钱!"); employee.Salary -= 20; ConsoleWriteline("扣完钱了,还剩" + employee.Salary); } } |
Main方法可以这么写:
1 2 3 4 5 6 7 | public static void Main(string[] args) { Manager currentManager = new Manager(); Employee currentWorker = new Employee(currentManager); currentWorker.PlayGame(); } |
现在运行程序,可以很好的输出结果。但是,以上程序有些问题:
- 必须先创建主管,然后才能创建员工,也就是说要创建有效的员工,必须先创建主管,耦合度太高了;
- 如果功能需求发生变化,例如不是主管监督,而是经理监督,那么不但要增加经理类,而且要修改员工类。
这个时候,可以考虑使用委托。可以理解为两步:
第一步,首先要定义一个委托,即让主管监视员工;
第二步,员工类里要有个事件(员工是激发该事件的对象),而这个事件由主管去执行。
定义委托:
public delegate void Play(Object Sender, System.EventArgs e)
注意,这里声明的是一个委托类型,而不是委托对象。这个委托类型是一个事件。也可以将委托类型声明为其它类型,例如int等。比如:delegate void MyDel(int value);
员工类的定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class Employee { public int salary = 8000; //省略属性 public event Play play; //创建事件对象 public Employee() { } public void PlayGame() { System.EventArgs e = new EventArgs(); OnPlayGame(this, e); } void OnPlayGame(object Sender, EventArgs e) { if(play != null) { play(Sender, e); } } } |
主管类里要实现一个方法,这个方法与委托的返回值和参数一样(相同签名),给委托调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Manager { public Manager() { } public void RemoveMoney(Object Sender, System.EventArgs e) { Employee emp = Sender as Employee; emp.salary -= 20; ConsoleWriteline("扣钱后还剩" + emp.salary); } } |
调用方法:
1 2 3 4 5 6 7 | Manager theManager = new Manager(); Employee theEmp = new Employee(); theEmployee.play += new play(theManager.Removemoney); e.PlayGame(); e.Playgame(); //玩一次扣一次 |
脑子不好使了,妈的,改天再琢磨,睡觉。