zoukankan      html  css  js  c++  java
  • C# 委托事件机制 订阅发布

    在看下文的时候,你先要明白一个问题,什么是委托,什么是事件。但其实很让人头疼无解的是,即使有的时候你明白了这些原理,但在实际的运用中还是一脸懵逼,无从下手。

    其实在很多的时候,你可能在wpf,winfrom的使用的多,不过这坑爹玩意又不能不去弄明白!

    委托和事件

    委托:方法作另一个方法的参数  和类一样,委托是用户自定义的类型,但是类是数据和方法的集合,而委托是持有一个或多个方法。

    delegate 不可思议这就是委托的代表关键词,然而随着C#的发展有了语法糖,很多人又使用了action ,function去代替了delegate,如ntf,

    .netcore的Task都离不开它们,但本文还是用原始的delegate,需要了解action,function的可以自寻查阅资料

    事件:建立在委托之上,通过机制某个类在发生某些特定的事情之后,通知其他类或对象正在发生的事情。event代表性关键字

    认识发布者和订阅者

    发布者定义一系列的事件,并提供一个注册的方法;订阅者向发布者注册,并提供一个可被回调的方法,也就是事件处理的程序。这时候

    当事件被触发,订阅者接收到通知,订阅者的提交所有方法被执行

    1.发布者拥有某些事件的类和结构

    2.订阅者向发布者注册类和结构

    3.事件处理指订阅者注册到事件的方法,在发布者出发被执行

    事件注册 :订阅者通过**+=**操作符来注册事件,并提供一个事件处理程序

    以上基本是通用的概念,但还是希望你去看下吧,好了下面开始正文:

    例子:比如某个班级,有class1,class2班别等等,向某位同学通知他的期末成绩修改变动。这里我们先考虑一下谁是订阅者,谁是发布者,事件应该写在哪里,触发事件又是什么

    其实上面也可以看成有个等级的分明,班级为发布者,订阅者为分数变动,某位同学。 引发函数的事件:分数变动  ,Student_Grade为事件的响应函数

    废话说了一大堆,好了直接上代码

    【1】定义分数事件的参数类,继承EventArgs,EventArgs是包含事件数据的类的基类,用于传递事件的细节。

     public class GradeChangeEventArg : EventArgs
            {
                public  string _name;
                public float _Grade;
    
                public GradeChangeEventArg(string name,int Grade)
                {
                    _name = name;
                    _Grade = Grade;
                }
            }
    

    【2】.定义分数变化的委托类型

    object sender:表示触发事件的控件对象  
    GradeChangeEventArgs arg:表示事件数据的类的基类

    public delegate void GradeChangeEventHandle(object sender, GradeChangeEventArg arg);  

    下面写个Student的实体,

    UpdateGrade 为一个触发事件的函数
    public class Student
            {
                public string _name;
    
                public Student(string name)
                {
                    _name = name;
                }
    
                public event GradeChangeEventHandle GradeChange;//它实际上就是GradeChangeEventHandle类型的委托
                //这里需要考虑怎么引发上面事件
                protected void OnGradeChange(GradeChangeEventArg arg)
                {
                    //if (GradeChange!=null)
                    //{
                    //    //GradeChange(this, arg);
                        
                    //}
    //简化可以写成这样,不懂得自行查阅资料 GradeChange?.Invoke(this,arg); } //更新学生名字和引发分数变化事件 public void UpdateGrade(string nm,int grade) { GradeChangeEventArg arg=new GradeChangeEventArg(nm, grade); this.OnGradeChange(arg); } }

    【3】.下面可以用Action的形式去代替原有的步骤2和事件GradeChange的定义,不明白的请自行查阅资料

    public Action<object,GradeChangeEventArg> GradeChange;
    Action写法

    【4】.ClassRoom实体,可以看出Student_Grade为事件的响应函数

            public class ClassRoom
            {
                public  string _classname;
    
                public ClassRoom(string classname)
                {
                    _classname = classname;
                }
    
                public void Student_Grade(object sender, GradeChangeEventArg arg)
                {
                    Student st = sender as Student;
                    Console.WriteLine($"{arg._name}班级{_classname}:同学{st._name}收到期末成绩通知为{arg._Grade}");
                }
            }

    【5】.Main函数  

            static void Main(string[] args)
            {
                Student student1 = new Student("Evan");
                Student student2 = new Student("Sola");
    
                ClassRoom classRoom1 = new ClassRoom("Class1");
                ClassRoom classRoom2 = new ClassRoom("Class2");
    
                student1.GradeChange += classRoom1.Student_Grade;
                student1.UpdateGrade("高三",98);
            }
    主体函数Main

     

    若要转载请附上作者原文链接  https://www.cnblogs.com/hexsola1314/p/13233907.html  Evan

     

  • 相关阅读:
    oracle 更改账户名密码
    mongodb 分片副本集搭建
    爬虫目录
    centos MySQL安装与卸载
    ANACONDA 安装
    chrome 安装
    linux pycharm 安装 idea
    linux 基本命令
    高数18讲 之极限与连续
    高数18讲 之基础知识
  • 原文地址:https://www.cnblogs.com/hexsola1314/p/13233907.html
Copyright © 2011-2022 走看看