zoukankan      html  css  js  c++  java
  • .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
  • 相关阅读:
    #JavaScript 闭包问题详解 #打倒心魔
    Typora + cnblog 图片自动上传 (超详细哦)
    #FUNCTION#CALL对象中的函数内作用域问题.md
    #windows #Github #HOST
    #######对象迭代器######
    #为什么不建议使用for...in 去遍历数组
    #前后端附件传输,去重的一种方式#解决方案
    #页面滚动刷新的实现原理 #下拉刷新#上拉刷新#drag to fresh
    自己动手实现一个阻塞队列
    APC注入
  • 原文地址:https://www.cnblogs.com/kongsq/p/10068783.html
Copyright © 2011-2022 走看看