委託事件

委託是一種數據類型,能夠把方法經過參數傳遞到另外一個方法中,關鍵字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);
    }
View Code

 

代碼應用例子: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

    }
View Code

實例化委託的方式,多播委託,委託+=,-=,同一個實例+=,-+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");
        }
    }
View Code

 

事件的聲明語法:對象

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();
}
View Code
相關文章
相關標籤/搜索