1.委托
委托的声明:
该委托返回值为空,参数为int类型的方法。
delegate void TestName(int a);
static void Funtion1(int b)
{
Console.WriteLine(b);
}
TestName=Funtion1;
TestName(5);
委托的实质是个类。可以声明在类里面(相当于嵌套类),可以声明在类外。使用的方式相当于C++里的方法指针,最开始是做回调函数使用。
2.事件
事件是基于委托存在的。一个事件的过程有:事件的拥有者,事件的响响应者,订阅器,事件的处理方法。
Demo:一个学生类有一个读书方法,触发这个的时候,触发相应的读书事件。
事件的拥有者:class Student
class Student {
public string Name { get; set; }
public void Reading(string arg) { e.BookName = arg;
this.OnRead();
}
ReadEventArgs e = new ReadEventArgs();
private ReadEventHandler _readEventHandler;
public event ReadEventHandler Read {
add { this._readEventHandler += value; }
remove { this._readEventHandler -= value; }
}
protected void OnRead() {
this._readEventHandler(this, e);
}
}
这个class里在声明事件Read的时候使用了ReadEventHandler进行了约束,这个类型为委托类型,根据约定命名后缀必须为EventHandler,声明方式为
delegate void ReadEventHandler(Student stu,ReadEventArgs e);
约束中的第一个参数为事件拥有者的类型,第二个为事件参数,用于附加信息,根据定义这个类型必须继承者EventArgs类
class ReadEventArgs:EventArgs {
public string BookName { get; set; }
}
使用的时候是直接声明类型变量对事件进行赋值+=和-=,赋上一个静态方法或者一个类型的方法
Student stu = new Student();
stu.Read += Stu_Read;
stu.Name = "小明";
stu.Reading("三国演义");
private static void Stu_Read(Student stu, ReadEventArgs e) {
Console.WriteLine($"{stu.Name}正在读{e.BookName}");
}
②
Student stu = new Student();
Book book = new Book();
stu.Read += book.Action;
stu.Name = "小明";
stu.Reading("三国演义");
class Book {
internal void Action(Student stu, ReadEventArgs e) {
Console.WriteLine($"{stu.Name}正在读{e.BookName}");
}
3.上面为事件比较繁琐的声明方式,像是EventHandler部分,我们可以直接使用EventHandler使用的时候再把参数中的Object,EventArgs转为相应的类型就可以。
现在经过编译器的语法糖,可以这样写。要注意的地方是在class类里面事件出现在了!=号左边,这里是由于C#的语法糖导致,在实例使用的时候事件只能出现在+=或者-=符号的左边。这就防止了其他的实例借用处理器,影响到本实例的数据(也是有委托还要使用事件的原因)。
class Student {
public string Name { get; set; }
public event EventHandler Read;
ReadEventArgs e = new ReadEventArgs();
protected void OnRead() {
if (Read!=null)
{
Read(this, e);
}
}
public void Reading(string arg1) {
e.BookName = arg1;
OnRead();
}
}
//事件参数
class ReadEventArgs:EventArgs {
public string BookName { get; set; }
}
//使用
Student stu = new Student();
stu.Read += Stu_Read;
stu.Name = "小明";
stu.Reading("三国演义");
private static void Stu_Read(object sender, EventArgs e) {
Student stu = new Student();
stu = (Student)sender;
ReadEventArgs readEventArgs = (ReadEventArgs)e;
Console.WriteLine($"{stu.Name}正在读{readEventArgs.BookName}");
}