.Net委托事件多播委托示例

委托是一种数据类型,可以把方法通过参数传递到另一个方法中,关键字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);
    }
View Code

代码应用例子:

    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

实例化委托的方式,多播委托,委托+=,-=,同一个实例+=,-+

多播委托:一个变量保存多个方法,可以增减;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");
        }
    }
View Code

事件的声明语法:

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();
}
View Code
原文地址:https://www.cnblogs.com/kongsq/p/10068783.html