一、委托的原理:
本质上委托是一种数据类型,他描述的是具有相同参数签名及返回值的一类方法。一个实例化的委托可以看做是一组具有相同参数签名及返回值的方法的列表。任何委托对象都是System.Delegate的某个派生类的一个对象。
二、定义委托:
///定义一个委托 delegate int Plus(int x,int y); //方法里面实例化委托 public void Test() { //可以New一个实例委托对象,必须指定一个函数 Plus p= new Plus(Num); //也可以直接指定一个函数 p += Num; //lambda表达式本质上也是一个函数,因此可以这样写 p +=(x,y)=>x+y; //当一个实例化的委托指定了多个方法,并且都有返回值时,执行委托时只能接受到最后一个方法的返回值 int a= p(1,2); } public int Num(int x,int y) { return x + y; }
三、c#内置委托,Action、Func
c#语法帮我们定义了两种默认的委托类型 Action及Func,Action委托可以有参数没有返回值,Func有返回值可以有参数、
//实例化一个Action委托 Action<string> sayHello=x=>{Console.Write(x);}; sayHello("你今天吃饭了吗?"); //实例化一个Func委托 Func<int, int, int> plus = (x, y) => { return x + y; }; var num= plus(1, 8);
四、委托的用法
1.当做参数在方法里面传递
public int Test() { //调用方法,将lambda表达式仿作参数传递 return Operation((x,y)=> { return x + y; },1,8); } public int Operation(Func<int,int,int> lam,int a,int b) { return lam(a,b); }
五、事件和委托的关系
事件是由一个私有的委托变量及add和remove两个方法组成的
定义一个事件复杂的写法:
/// <summary> /// /事件发布者类-学生 定义事件复杂的写法 /// </summary> public class Student { public string Name { get;set; } private int age; public int Age { get { return age; } set { this.age = value; if (this.age % 12==0) { if (onBenMingNian != null) { //触发事件 onBenMingNian(); } } } } //声明事件 private Action onBenMingNian; public event Action OnBenMingNian { add { this.onBenMingNian += value; } remove { this.onBenMingNian -= value; } } }
定义一个事件简单的写法:
/// <summary> /// 事件订阅者 /// </summary> public void Test() { var stu = new Student(); int i = 0; //向事件添加处理函数 stu.OnBenMingNian += () => { i += 1; Console.Write("骚年本命年到了,别撸代码了,休息吧"); }; stu.Age = 12; } } /// <summary> /// /事件发布者类-学生 /// </summary> public class Student { public string Name { get;set; } private int age; public int Age { get { return age; } set { this.age = value; if (this.age % 12==0) { if (OnBenMingNian != null) { //触发事件 OnBenMingNian(); } } } } //声明事件 public event Action OnBenMingNian; }
由此可以看出我们对事件+=或者-+操作就是在对所有事件变量的add或者remove方法。事件不能赋值为null。