C#基础知识学习之 ✨ 委托(delegate) 与 事件(event) 之间的介绍

举报
呆呆敲代码的小Y 发表于 2021/07/26 22:34:57 2021/07/26
【摘要】 委托(delegate) 与 事件(event) 🔥 前言🙏 在之前的文章里介绍了C#中的委托(delegate) (Action、Func、Predicate)的基本含义及用法 那本篇文章在这里还要介绍一个跟委托有很大关系的小伙伴——C#中的 事件(event)🎅 事件跟委托是有很大联系的,所以也就导致很容易分不清他们两个,以及什么时候用这两个 上面有博...

委托(delegate) 与 事件(event) 🔥

前言🙏

在之前的文章里介绍了C#中的委托(delegate)
(Action、Func、Predicate)的基本含义及用法

那本篇文章在这里还要介绍一个跟委托有很大关系的小伙伴——C#中的 事件(event)🎅
事件跟委托是有很大联系的,所以也就导致很容易分不清他们两个,以及什么时候用这两个

上面有博客提到委托,想单独了解委托的可以去看一下,本篇文章主要说一下 什么是事件 🎄
以及 事件与委托的区别🎁


委托和事件的定义 💬

委托

在这里再说一遍委托跟事件的简单定义(没有搜到特别准确的,都是大概定义,理解万岁)

委托:delegate 是一种可用于封装命名或匿名方法的引用类型。 委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。

委托是一种动态调用方法的类型,属于引用型。
委托是对方法的抽象和封装。委托对象实质上代表了方法的引用(即内存地址)
委托允许将方法作为参数进行传递。
委托可用于定义回调方法。
委托可以把多个方法链接在一起。这样,在事件触发时可同时启动多个事件处理程序。
委托签名不需要与方法精确匹配。


事件

事件:事件是特殊类型的多路广播委托,仅可从声明它们的类或结构(发行者类)中调用。
如果其他类或结构订阅了该事件,则当发行者类引发该事件时,会调用其事件处理程序方法。

事件表示C#中已定义的一个对象,即处理通知过程的对象
通常,每个事件的发生都会产生发送方和接收方。在.net框架中,事件是将事件发送者(触发事件的对象)与事件接受者(处理事件的方法)相关联的一种代理类,即事件机制是通过代理类来实现的。当一个事件被触发时,由该事件的代理来通知(调用)处理该事件的相应方法

委托和事件的区别

简单说了一下两者的定义,眼神好的小伙伴这时候就会发现,事件的说明里有提到一句话:“事件也可以算一种特殊的委托”,这句话不是特别准确,但是也不妨可以这样理解。
正因为如此,所以要我们先了解了 委托 再来看 事件 ,容易混淆大家的地方大多在于这两者之间的区别,下面说一下委托和事件之间的区别:

委托和事件的区别如下:

区别 委托 事件
1 是否是一个类型 否,事件修饰的是一个对象
2 是否可以在类外部进行调用
3 是否可以使用=来赋值

举例说明

我们将创建两个类ClassA和ClassB,这两个类都很简单,只有一个方法,并且这两个类的方法签名一样。ClassC内有委托和事件,为了演示方便,我们将委托和事件的访问权限都设为public。下面我们将主要看看委托和事件在使用上面的区别。

Class1

public class Class1
{ //声明委托 public delegate void NumberChanger(int n); //声明事件 public static event NumberChanger changer; public static void test() { changer(100); } static void Main(string[] args) { Class1.changer += Class2.ClassA_Test; Class1.changer += Class3.ClassA_Test; Class1.test(); }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Class2

 class Class2 { public static void ClassA_Test(int i) { Console.WriteLine("Class2:"+i); } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Class3

 class Class3 { public static void ClassA_Test(int i) { Console.WriteLine("Class3:"+i); } }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
区别一:是否是一个类型
 class Class3 { static void Main(string[] args) { //委托正确使用 Class1.NumberChanger n1 = Class2.ClassA_Test; //事件使用 编译器报错 Class1.changer handle2 = Class2.ClassA_Test; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

错误:Class1.changer 是“字段”,但此处被当做“类型”来使用

区别二:委托可以在声明它的类外部进行调用,而事件只能在类的内部进行调用。

(1)在类外部调用委托
在这里插入图片描述

(2)在类外部调用事件
在这里插入图片描述

事件“ClassC.Say_EventHandler”只能出现在 += 或 -= 的左边(从类型“ClassC”中使用时除外)

区别三:委托可以在外部类使用 = 来赋值,事件只能在内部类用 = 赋值,外部类不可以

在这里插入图片描述

从编译器提示的错误,我们可以了解到,事件只能在声明它的类内部被调用。从事件本身来讲,事件一般用于类自身的属性变化时,用来通知外界自身的变化的。我们将对ClassC内部的一个属性赋值,然后调用事件,模拟对外通知。代码如下所示
在这里插入图片描述


总结 🏠

事件的使用方式跟委托没什么区别,事件就相当于一个加了"event"修饰符的委托,在加了这个修饰以后,委托的部分功能就相当于被阉割了。通过这个加了修饰符以后,我们可以更好的控制注册和注销,对于一个外部类来说,它就只能通过"+=/-="注册自己和注销自己,而且外界也不能主动触发一个事件。

委托一般用于回调,而事件用于外部接口。例如在观察者模式中,在被观察者中可以声明一个事件作为外部观察者注册的接口。
同时,这个事件只能在被观察者内部触发,而观察者中无法触发该事件,从而保证了安全性。

说了这么多,总结起来就一句话:事件与委托最主要的区别应该是不能在外部调用,但可以通过+=或-=进行注册,但如果委托变量为私有,则外部不能注册;如果为公有,则外部有可以调用,破坏了封装,所以没办法,在这种情况就定义一个event就好了

文章来源: blog.csdn.net,作者:呆呆敲代码的小Y,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/zhangay1998/article/details/115975249

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。