委託是一種數據類型,能夠把方法經過參數傳遞到另外一個方法中,關鍵字delegate。異步
能夠聲明與類相同級別,或與屬性相同級別,能夠有返回值沒返回值,有參數,沒參數 。聲明例子:ide
/// <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); }
代碼應用例子:this
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 }
實例化委託的方式,多播委託,委託+=,-=,同一個實例+=,-+spa
多播委託:一個變量保存多個方法,能夠增減;invoke的時候能夠按順序執行code
/// <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(委託名字) 事件名字 ;blog
代碼:繼承
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(); }