C#基础(一) 委托和事件

delegate关键字和System.(MultiCast)Delegate类型

C#的委托,使用delegate关键字来表示,通过以下方式可以声明一个委托类型

namespace XXX
{
    // 这里看到delegate修饰的关键字与下方的class同级,而并非需要在class内部
    public delegate void MyDelegate()

    public class MyClass
    {

    }
}

注意在措辞上,我们说这里是声明了一个类型,而非定义了一个变量,或是定义了一个字段,属性,亦或是事件。这表示在层级上,声明一个委托(delegate)就和声明一个类一样,它只是声明了一个类型模板,需要在需要的地方创建它的实例,例如MyClass myClass1,MyClass myClass2,MyDelegate myDelegate1。如果对C语言比较熟悉的话,这就相当于声明了一个结构体,和一个函数指针,类似如下:

typedef void (*MyDelegate)()

struct MyClass {

};

所以说声明委托的语句应当和声明class是平级的关系,也就是都从属于某个namespace下。然而在C#语法中,也允许在一个class的内部去声明一个委托类型,类似语法上也可以在类中再定义一个类。

在类中定义委托实例的字段时,编译器会生成System.Delegate以及派生类System.MultiCastDelegate类型对象。在官方文档中提到初始设计时是希望分成单播委托和多播委托的,但是最后实际应用时发现效果并不好,所以在目前版本.Net 6.0中,使用的都是多播委托即System.MultiCastDelegate。

https://learn.microsoft.com/zh-cn/dotnet/csharp/delegate-class

Action, Func, Predicate, Comparison类型

这些类型本质上是上一节中提到的delegate委托类型声明,它们被包含在System namespace下。.Net Standard自带了这些类型作为基础库,原因是它们是非常常用的一些委托类型(委托类型实际就是指函数返回值,形参的不同,也可以称为函数签名,即function prototype),所以为了方便使用预先将他们内置在了基础库之中,这样就不用每个项目中单独去创建委托声明了。

Action

Func

Predicate

Comparison

event关键字和EventHandler, EventArgs类型

event关键字相当于是对委托的再次封装,首先event关键字后面跟的必须是一个委托类型,这个委托类型可以是自己创建的,也可以是System中预定义的,这包含了上一节提到的Action,Func等,也包含EventHandler这种类型的委托,它是相当于void EventHandler(object, EventArgs)类型的委托。

所以,可以把event当作是delegate的一种特殊形式,特殊点在于,当一个delegate类型被定义为一个event字段后,它的可操作性就变得被封装起来了,外部去访问这个event字段,只能进行+=和-=,即订阅和取消订阅这两种模式。而对于不加event修饰的delegate类型字段,它具有更多的暴露操作,例如可以直接赋值,通过反射获得Method类型等,它也可以具有event的用法即+=和-=,但是它也具备event不具备的用法,比如直接赋值,比如作为一个方法的参数而不是类的字段,例如public void Sort(Comparison comparison)这样的用法。

总结

原始的delegate

系统预定义了delegate通用函数签名如Action,Func,Predicate,Comparison

系统虽然预定义了,但是还是属于delegate范畴,无法很好的作为观察者模式的一个接口(这里是指暴露的操作权限过多,而不是说不能实现观察者模式的功能)。

所以编译器又衍生了event关键词,并为其制定了语言层面的规则和语法糖,delegate会被视为普通字段,event会被单独列出作为闪电图标。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值