委托与事件

委托

实际上用类完成了函数指针的功能

使用步骤

声明

1
delegate void Print(int x)  //只能在namespace和类下

初始化,赋值

1
2
Print someFunc = hello;
Print someFunc = new Print(hello);

调用委托变量

1
someFunc(30);

例子

1
2
3
4
5
public delegate void PrintInt(int x)

public void Hello(int x) => Console.WriteLIne($"{x}");

PrintINt writeInt = Hello(354);

多播委托

多播委托将多个函数对象分配到一个委托示例

委托的分配动作是通过 += 、-= 完成的(可以用=。 事件不能用=)

事件

事件是一种特殊的委托

组成

事件拥有者,事件成员,事件相应者,事件处理器,事件订阅

image-20241209223501574

主流理解是将代码分为两个部分:事件发布者(广播者)和事件订阅者(订阅者)

简称SB模式

最大的好处是不能赋值。

实现思路

  1. 在类中定义私有化委托
  2. 暴露出-=、+=的方法
1
2
3
4
5
public delegate void FuncHandler(int item);
public class Broadcaster
{
public event FuncHandler funcHandler; //事件的声明
}

事件的标准写法

  1. 命名事件的委托必须以EventHandler结尾

  2. 触发函数必须以On开头,且必须是虚函数

  3. 订阅者(+=、-=)函数的类型符合EventHandler委托类型

    1. 接收两个参数(object arg1, SomeEventArgs arg2)

      ​ arg1 表示广播者

      ​ arg2 参数为EventArgs的子类 表示传播信息

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public delegate void MyDelegate(string str);

public event MyDelegate MyEvent;

public void OnEventHappend()
{
MyEvent?.Invoke("happened");
}

public void Display(string s)
{
Console.WriteLine(s);
}

static void Main()
{
//1. 定义一个事件,然后把这个事件注册到某个响应上
MyEvent += Display //会输出happened
Peoople p = new People();
MyEvent += p.PeopleResponed;
OnEventHappend();//事件的触发
}

class Animal
{
public void AnimalRespond(string s) //效应
{
Console.WriteLine("Animal Responed")
}
}

class People
{
public void PeopleRespond(string s)
{
Console.WriteLine("People Responed")
}
}