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的定义,不明白的请自行查阅资料
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public Action<object,GradeChangeEventArg> GradeChange;
【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函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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); }
若要转载请附上作者原文链接 https://www.cnblogs.com/hexsola1314/p/13233907.html Evan