委托是一种数据类型,可以把方法通过参数传递到另一个方法中,关键字delegate。
可以声明与类相同级别,或与属性相同级别,可以有返回值没返回值,有参数,没参数 。声明例子:
/// <summary> /// 委托:是一个类,继承自System.MulticastDelegate,里面内置了几个方法 /// </summary> public delegate void NoReturnNoParaOutClass(); public class MyDelegate { public delegate void NoReturnNoPara<T>(T t); public delegate void NoReturnNoPara(); public delegate void NoReturnWithPara(int x, int y);//1 声明委托 public delegate int WithReturnNoPara(); public delegate string WithReturnWithPara(out int x, ref int y); }
代码应用例子:
public class ListExtend { public delegate bool ThanDelegate(Student student); private bool Than(Student student) { return student.Age > 25; } private bool LengthThan(Student student) { return student.Name.Length > 2; } private bool AllThan(Student student) { return student.Name.Length > 2 && student.Age > 25 && student.ClassId == 2; } public void Show() { List<Student> studentList = this.GetStudentList(); { //找出年龄大于25 List<Student> result = new List<Student>();//准备容器 foreach (Student student in studentList)//遍历数据源 { if (student.Age > 25)//判断条件 { result.Add(student);//满足条件的放入容器 } } Console.WriteLine($"结果一共有{result.Count()}个"); } { //this.GetList(studentList, 1); ThanDelegate method = new ThanDelegate(this.Than);//返回值和参数一样就行 LengthThan AllThan 都可以传 List<Student> result = this.GetListDelegate(studentList, method); Console.WriteLine($"结果一共有{result.Count()}个"); } { //找出Name长度大于2 List<Student> result = new List<Student>(); foreach (Student student in studentList) { if (student.Name.Length > 2) { result.Add(student); } } Console.WriteLine($"结果一共有{result.Count()}个"); } { //this.GetList(studentList, 2); ThanDelegate method = new ThanDelegate(this.LengthThan); List<Student> result = this.GetListDelegate(studentList, method); Console.WriteLine($"结果一共有{result.Count()}个"); } { //找出Name长度大于2 而且年龄大于25 而且班级id是2 List<Student> result = new List<Student>(); foreach (Student student in studentList) { if (student.Name.Length > 2 && student.Age > 25 && student.ClassId == 2) { result.Add(student); } } Console.WriteLine($"结果一共有{result.Count()}个"); } { //this.GetList(studentList, 3); ThanDelegate method = new ThanDelegate(this.AllThan); List<Student> result = this.GetListDelegate(studentList, method); Console.WriteLine($"结果一共有{result.Count()}个"); } } /// <summary> /// 1 type:不同的值 不同的判断 如果再多一种 /// /// 传个参数--判断参数--执行对应的行为 /// 那我能不能直接传递个行为呢?逻辑就是方法,等于说传递方法进来 /// /// </summary> /// <param name="source"></param> /// <returns></returns> private List<Student> GetList(List<Student> source, int type) { List<Student> result = new List<Student>(); foreach (Student student in source) { if (type == 1) { if (student.Age > 25)//判断条件 { result.Add(student);//满足条件的放入容器 } } else if (type == 2) { if (student.Name.Length > 2) { result.Add(student); } } else if (type == 3) { if (student.Name.Length > 2 && student.Age > 25 && student.ClassId == 2) { result.Add(student); } } } return result; } /// <summary> /// 判断逻辑传递进来+实现共用逻辑 /// 委托解耦,减少重复代码 /// </summary> /// <param name="source"></param> /// <param name="method"></param> /// <returns></returns> private List<Student> GetListDelegate(List<Student> source, ThanDelegate method) { List<Student> result = new List<Student>(); foreach (Student student in source) { if (method.Invoke(student)) { result.Add(student); } } return result; } #region 数据准备 /// <summary> /// 准备数据 /// </summary> /// <returns></returns> private List<Student> GetStudentList() { #region 初始化数据 List<Student> studentList = new List<Student>() { new Student() { Id=1, Name="老K", ClassId=2, Age=35 }, new Student() { Id=1, Name="hao", ClassId=2, Age=23 }, new Student() { Id=1, Name="大水", ClassId=2, Age=27 }, new Student() { Id=1, Name="半醉人间", ClassId=2, Age=26 }, new Student() { Id=1, Name="风尘浪子", ClassId=2, Age=25 }, new Student() { Id=1, Name="一大锅鱼", ClassId=2, Age=24 }, new Student() { Id=1, Name="小白", ClassId=2, Age=21 }, new Student() { Id=1, Name="yoyo", ClassId=2, Age=22 }, new Student() { Id=1, Name="冰亮", ClassId=2, Age=34 }, new Student() { Id=1, Name="瀚", ClassId=2, Age=30 }, new Student() { Id=1, Name="毕帆", ClassId=2, Age=30 }, new Student() { Id=1, Name="一点半", ClassId=2, Age=30 }, new Student() { Id=1, Name="小石头", ClassId=2, Age=28 }, new Student() { Id=1, Name="大海", ClassId=2, Age=30 }, new Student() { Id=3, Name="yoyo", ClassId=3, Age=30 }, new Student() { Id=4, Name="unknown", ClassId=4, Age=30 } }; #endregion return studentList; } #endregion }
实例化委托的方式,多播委托,委托+=,-=,同一个实例+=,-+
多播委托:一个变量保存多个方法,可以增减;invoke的时候可以按顺序执行
/// <summary> /// 委托:是一个类,继承自System.MulticastDelegate,里面内置了几个方法 /// </summary> public delegate void NoReturnNoParaOutClass(); public class MyDelegate { public delegate void NoReturnNoPara<T>(T t); public delegate void NoReturnNoPara(); public delegate void NoReturnWithPara(int x, int y);//1 声明委托 public delegate int WithReturnNoPara(); public delegate string WithReturnWithPara(out int x, ref int y); public void Show() { //System.MulticastDelegate Student student = new Student() { Id = 123, Name = "靠谱一大叔", Age = 32, ClassId = 1 }; student.Study(); { //把方法包装成对象,invoke的时候自动执行方法 NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);//2 委托的实例化 method.Invoke();//3 委托实例的调用 method(); this.DoNothing(); } //begininvoke { WithReturnNoPara method = new WithReturnNoPara(this.GetSomething); int iResult = method.Invoke(); iResult = method(); var result = method.BeginInvoke(null, null);//异步调用 method.EndInvoke(result); } { //多种途径实例化 { NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);//当前类型的实例化方法 } { NoReturnNoPara method = new NoReturnNoPara(DoNothingStatic);//当前类型的静态方法 } { NoReturnNoPara method = new NoReturnNoPara(Student.StudyAdvanced);//其他类型的静态方法 } { NoReturnNoPara method = new NoReturnNoPara(new Student().Study);//其他类型的实例化方法 } } { //多播委托:一个变量保存多个方法,可以增减;invoke的时候可以按顺序执行 //+= 为委托实例按顺序增加方法,形成方法链,Invoke时,按顺序依次执行 Student studentNew = new Student(); NoReturnNoPara method = new NoReturnNoPara(this.DoNothing); method += new NoReturnNoPara(this.DoNothing); method += new NoReturnNoPara(DoNothingStatic); method += new NoReturnNoPara(Student.StudyAdvanced); method += new NoReturnNoPara(new Student().Study);//不是同一个实例,所以是不同的方法 method += new NoReturnNoPara(studentNew.Study); method.Invoke(); //method.BeginInvoke(null, null);//多播委托是不能异步的 foreach (NoReturnNoPara item in method.GetInvocationList()) { item.Invoke(); //item.BeginInvoke(null, null); } //-= 为委托实例移除方法,从方法链的尾部开始匹配,遇到第一个完全吻合的,移除且只移除一个,没有也不异常 method -= new NoReturnNoPara(this.DoNothing); method -= new NoReturnNoPara(DoNothingStatic); method -= new NoReturnNoPara(Student.StudyAdvanced); method -= new NoReturnNoPara(new Student().Study); method -= new NoReturnNoPara(studentNew.Study); method.Invoke(); } { WithReturnNoPara method = new WithReturnNoPara(this.GetSomething); method += new WithReturnNoPara(this.GetSomething2); method += new WithReturnNoPara(this.GetSomething3); int iResult = method.Invoke();//多播委托带返回值,结果以最后的为准 } } private int GetSomething() { return 1; } private int GetSomething2() { return 2; } private int GetSomething3() { return 3; } private void DoNothing() { Console.WriteLine("This is DoNothing"); } private static void DoNothingStatic() { Console.WriteLine("This is DoNothingStatic"); } }
事件的声明语法:
public event Delegate(委托名字) 事件名字 ;
代码:
namespace MyDelegateEvent.Event { /// <summary> /// 发布者 /// 一只猫,miao一声 /// 导致一系列的触发动作 /// /// 直接调用别的实例的别的方法 /// 不管是增/减/顺序 都会让猫不稳定 /// /// 发布者 /// </summary> public class Cat { public void Miao() { Console.WriteLine("{0} Miao", this.GetType().Name); new Mouse().Run(); new Baby().Cry(); new Mother().Wispher(); //new Brother().Turn(); new Father().Roar(); new Neighbor().Awake(); new Stealer().Hide(); new Dog().Wang(); } //猫 叫一声 触发一系列后续动作 //多了个 指定动作 正是这个不稳定 封装出去 甩锅 public MiaoDelegate MiaoDelegateHandler; public void MiaoNew() { Console.WriteLine("{0} MiaoNew", this.GetType().Name); if (this.MiaoDelegateHandler != null) { this.MiaoDelegateHandler.Invoke(); } } //事件:是带event关键字的委托的实例,event可以限制变量被外部调用/直接赋值 //委托和事件的区别与联系? //委托是一个类型,比如Student //事件是委托类型的一个实例,比如 果然 public event MiaoDelegate MiaoDelegateHandlerEvent; public void MiaoNewEvent() { Console.WriteLine("{0} MiaoNewEvent", this.GetType().Name); if (this.MiaoDelegateHandlerEvent != null) { this.MiaoDelegateHandlerEvent.Invoke(); } } //观察者模式 } public class ChildClass : Cat { public void Show() { this.MiaoDelegateHandlerEvent += null; //if (this.MiaoDelegateHandlerEvent != null)//子类也不能调用 //{ // this.MiaoDelegateHandlerEvent.Invoke(); //} } } public delegate void MiaoDelegate(); }