c#学习笔记 ------委托和事件篇

📅 发布时间:2026/7/3 18:25:37 👁️ 浏览次数:
c#学习笔记 ------委托和事件篇
c#委托的基本概念委托Delegate是C#中的一种类型用于封装方法函数的引用类似于函数指针或回调机制。委托允许将方法作为参数传递、存储在变量中或动态调用是实现事件驱动和回调模式的核心机制。委托的特点类型安全委托在编译时检查方法签名参数类型和返回值确保调用的方法匹配委托定义。多播能力一个委托实例可以绑定多个方法调用时会按顺序执行所有方法通过操作符添加。灵活性支持匿名方法、Lambda表达式和事件封装委托的定义使用定义delegate作为返回类型垢面跟委托名public delegate string Mydelegate();使用我们想要使用委托需要先创建一个委托实例再将一个具有匹配签名的方法赋值给他方法我们可以使用静态的实例的或者是lambda表达式单播演示一个委托中注册一个方法​ Mydelegate d1 new Mydelegate(Fn1); Mydelegate d2 new Mydelegate(Fn2); Mydelegate d3 new Mydelegate(Fn3);Mydelegate d1 new Mydelegate(Fn1); ​多播演示委托多播允许在一个委托中注册多个方法在内部维护了一个的委托数组。按照添加的顺序依次调用方法。通过(添加方法)和-(删除方法)操作符管理这是一种写法//单播 Mydelegate d1 new Mydelegate(Fn1); Mydelegate d2 new Mydelegate(Fn2); Mydelegate d3 new Mydelegate(Fn3); //组合成一个委托多播委托 Mydelegate d4 d2 d1 d3;//相当于d4绑定3个方法另一种写法以及添加方法和删除方法//第二种以及添加删除方法管理操作 Mydelegate d5 Fn1; d5 Fn2; d5 Fn3;重点 - 删除方法的局限如果添加的方法是匿名方法或者lamda写法就无法删除调用委托同步调用注意委托在编译时会严格校验方法签名确保类型匹配和调用安全//只返回最后一个方法的返回值 string rs d5(); Console.WriteLine($输出返回值{rs});上图这种调用方法只会返回最后一个方法的返回值如果需要每个方法的返回值获取的是delegate[]GetUnvocationList获取多播委托的执行链集合iststring rslist new Liststring(); Delegate[] delegatesArr d5.GetInvocationList(); foreach (var item in delegatesArr) { Mydelegate d item as Mydelegate; string result d(); rslist.Add(result); } Console.WriteLine(string.Join(\n, rslist)); }异步调用使用委托实例的BeginInvoke方法可以进行委托的异步调用该方法会使用一个后台线程进行异步的操作。参数列表中除去最后两个之外与委托参数列表相同最后两个参数分别传入回调方法、异步状态值(不使用可以传入null)。// 使用 BeginInvoke 进行异步调用 d5.BeginInvoke(callback, null);委托的类型C# 提供了几个常用的内置委托类型这些委托可以更方便地用于常见的编程模式Action无返回值的方法类型通常用于处理不需要返回值的操作。Func有返回值的方法类型最多可以接受 16 个输入参数。Predicate返回布尔值的方法类型通常用于条件判断。一Action委托ActionT是.NET Framework内置的泛型委托可以使用ActionT委托以参数形式传递方法而不用显示声明自定义的委托。封装的方法必须与此委托定义的方法签名相对应。也就是说封装的方法必须具有一个通过值传递给它的参数并且不能有返回值。二Func委托、 Func 是 C# 中的一个泛型委托类型用于表示带有返回值的方法。Func 委托有多种重载形式可以接受 0 到 16 个输入参数最后一个泛型参数总是表示返回值类型。三Predicate委托Predicate 是 C# 中的一个泛型委托专门用于表示对指定对象的条件判断方法。它返回一个布尔值表示对象是否满足特定条件。事件事件的概念在C#中事件是一种特殊的委托类型用于实现发布-订阅模式。事件允许类或对象在特定动作发生时通知其他类或对象而无需直接依赖它们。事件的核心是委托Delegate它定义了事件的签名和调用方式。事件的关键组成部分委托Delegate事件基于委托委托定义了事件处理方法的签名。例如EventHandler是.NET框架中预定义的委托类型。事件声明使用event关键字声明事件并指定关联的委托类型。事件发布者触发事件的类或对象通过调用事件通知订阅者。事件订阅者通过运算符注册事件处理方法在事件触发时执行逻辑。事件的声明与使用事件的本质还是一种委托所以声明一个事件之前还是必须需要声明一个相对应的委托在c#中事件需要使用关键字event来声明//相对应的委托 public delegate void TimeUpEventHandler(object sender, EventArgs e); //事件的声明 public event TimeUpEventHandler TimeUp;发布者类public delegate void TimeUpEventHandler(object sender, EventArgs e); internal class Timer { //相对应的委托 //事件的声明 public event TimeUpEventHandler TimeUp; public void Start(int seconds) { if (seconds 0) { Console.WriteLine(请设置大于0的秒数); return; } Console.WriteLine($启动{seconds}秒计时器); Console.WriteLine($计时器启动将在 {seconds} 秒后触发事件); Thread.Sleep(seconds * 1000); Console.WriteLine(计时器已停止); Console.WriteLine(时间到触发事件); TimeUp.Invoke(this, EventArgs.Empty); } }订阅者类namespace Demo1 { internal class Program { static void Main(string[] args) { Timer timer new Timer(); timer.TimeUp Timer_TimeUp; timer.Start(5); } private static void Timer_TimeUp(object sender, EventArgs e) { Console.WriteLine(时间到了执行特定操作); } } }在上例中我们创建了发布者类Timer和订阅者类Program直接把订阅者类中的Timer_TimeUp方法传递给了Timer.TimeUp事件用于执行。关键点总结四、关键要点总结要点说明委托是类型定义方法签名可存储方法引用事件是委托的封装增加安全限制外部只能订阅/取消不能直接触发发布-订阅分离发布者只负责触发订阅者只负责响应降低耦合多播委托一个事件可绑定多个处理方法异步支持委托支持BeginInvoke异步调用内置委托优先优先使用Action、Func而非自定义委托