C# 委托和事件
目录
概述
委托
前提知识:
微软官方文档/C#概念/委托和事件
MulticastDelegate类
Delegate类
定义
- 当我们使用
delegate
关键字在程序中声明一个委托类型:
| public delegate int Comparison<in T>(T left, T right); |
- 编译器会在我们使用
delegate
关键字声明委托类型时,创建派生自System.MulticastDelegate
,且与委托签名相同的类:

System.Delegate
类及其单个直接子类System.MulticastDelegate
可提供框架支持,以便创建委托、将方法注册为委托目标以及调用注册为委托目标的所有方法。该委托编译后大致如下:
| public class Comparsion<T> : System.MulticastDelegate |
| { |
| |
| public extern Comparison(object @object, IntPtr method); |
| |
| |
| public virtual extern IAsyncResult BeginInvoke(T left, T right, AsyncCallback callback, object @object); |
| |
| |
| public virtual extern int EndInvoke(IAsyncResult result); |
| |
| |
| public virtual extern int Invoke(T left, T right); |
| |
| } |
- 编译器会为委托类型生成
添加
和移除
处理程序,以便可以对委托的实例添加和移除方法调用:
继承自System.MulticastDelegate类的添加方法调用
:
| protected sealed override Delegate CombineImpl(Delegate? follow); |
自称子System.MulticastDelegate类的移除方法调用
:
| protected sealed override Delegate? RemoveImpl(Delegate value); |
向委托添加调用目标
- 我们根据声明的委托类型Comparison声明一个委托实例
comparator
:
| public Comparison<string> comparator; |
- 我们需要定义与委托类型签名匹配的方法
CompareLength
,并将它分配给委托实例comparator
:
| private int CompareLength<string>(string left, string right) |
| { |
| return left.Length.CompareTo(right.Length); |
| } |
| |
| comparator = CompareLength; |
- 调用委托:
| int result = comparator("apple", "banana"); |
| Console.WriteLine(result); |
.NET Core框架提供的可重用的委托类型
Action:对任何具有void返回类型的委托都可以使用Action类型
| public delegate void Action(); |
| public delegate void Action<in T>(T arg); |
| public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2); |
Func:对任何具有任意返回类型的委托都可以使用Func类型,返回值类型为Func声明中的最后一个类型参数。
| public delegate TResult Func<out TResult>(); |
| public delegate TResult Func<in T1, out TResult>(T1 arg); |
| public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2); |
Predicate:返回单个值测试结果
| public delegate bool Predicate<in T>(T obj); |
其中,以下Predicate类型和Func类型在结构
上是等效的,但是这两个类型变量不能互换使用,因为C#类型系统使用的是已定义类型的名称
。
| Func<string, bool> TestForString; |
| Predicate<string> AnotherTestForString; |
事件
前提知识:
定义
- 事件是对象用于(向系统中的所有相关组件)广播已发生事情的一种方式。
- 任何其他组件都可以订阅事件,并在事件引发时得到通知。
- 事件是建立在对委托的语言支持之上。
- 事件基于多播委托,对任何事件源都支持多个订阅服务器。
事件委托签名(Event delegate signatures)如下:
| void EventRaised(object sender, EventArgs args); |
EventHandle委托
EventHandle是一个委托类型,无返回值。此泛型委托类型的第一个参数的类型为object,引用触发事件的实例;第二个参数派生自类型EventArgs,提供保存事件数据所需的任何字段和属性,如果触发的事件不包含任何附加信息,可以使用EventArgs.Empty。
| public delegate void EventHandler<TEventArgs>(object? sender, TEventArgs e); |
在C#中,EventHandle经常与event一起使用,EventHandle是一个特殊的委托类型,它定义了事件处理方法的标准签名,而event关键字用于声明一个事件,它们一起使用来构建事件通知机制:
| public event EventHandler<TEventArgs> MyEvent; |
参考文章
- 委托和事件
https://learn.microsoft.com/zh-cn/dotnet/csharp/delegates-overview
文章声明
- 内容准确性:我会尽力确保所分享信息的准确性和可靠性,但由于个人知识有限,难免会有疏漏或错误。如果您在阅读过程中发现任何问题,请不吝赐教,我将及时更正。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!