每个.NET开发都应掌握的C#委托事件知识点
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
C#作为.NET开发的核心语言之一,提供了丰富的特性来支持面向对象编程和事件驱动的模型。其中,委托和事件是C#中不可或缺的关键概念,每个.NET开发者都应该深入理解它们的作用和用法。委托和事件密不可分,所以本文将委托和事件的知识点一起介绍,并通过一些示例来帮助开发者更好地掌握这些重要的概念。 一、委托 委托让方法引用的灵活利用 1、委托的定义与使用 委托是一种数据类型,用于持有对一个或多个方法的引用。通过委托,你可以将方法作为参数传递给其他方法,实现回调机制,实现方法的动态调用。使用`delegate`关键字可以声明委托类型,并创建委托实例来绑定具体方法。
使用try.dot.net的测试结果: 2、委托的多播 委托不仅可以持有单个方法的引用,还可以用于多播,即将多个方法绑定到同一个委托实例。多播委托允许按顺序调用这些方法,实现一次触发多个方法的功能。 using System; delegate void MyDelegate(); // 定义委托 class EventPublisher { private MyDelegate eventHandlers; // 多播委托实例 public void AddHandler(MyDelegate handler) { eventHandlers += handler; // 添加委托方法到多播链 } public void RemoveHandler(MyDelegate handler) { eventHandlers -= handler; // 从多播链中移除委托方法 } public void RaiseEvent() { Console.WriteLine("事件发布者正在引发事件..."); eventHandlers?.Invoke(); // 调用多播链中的委托方法 } } class Program { static void Main(string[] args) { EventPublisher publisher = new EventPublisher(); // 添加多个事件处理程序到多播链 publisher.AddHandler(Method1); publisher.AddHandler(Method2); publisher.AddHandler(Method3); // 触发事件,调用多播链中的所有方法 publisher.RaiseEvent(); // 移除一个事件处理程序 publisher.RemoveHandler(Method2); // 再次触发事件 publisher.RaiseEvent(); Console.ReadKey(); } static void Method1() { Console.WriteLine("方法1运行."); } static void Method2() { Console.WriteLine("方法2运行."); } static void Method3() { Console.WriteLine("方法3运行."); } } 输出结果: 3、 匿名方法与Lambda表达式 C# 2.0 引入了匿名方法,允许在没有显示声明方法的情况下传递代码块作为委托参数。而Lambda表达式则是C# 3.0 的新特性,提供了更简洁的语法来创建委托实例。.NET的ORM框架EF中有了Lambda表达式方便多了。 进化:委托-->匿名方法-->Lambda 案例:下面案例是委托匿名方法和Lambda表达式三种使用案例 using System; using System.Linq; delegate int MathOperation(int a, int b); class Calculator { public int Add(int a, int b) { return a + b; } public int Subtract(int a, int b) { return a - b; } } class Program { static void Main(string[] args) { Calculator calculator = new Calculator(); // 1、使用委托和实例方法 Add MathOperation operation1 = calculator.Add; int result1 = operation1(10, 5); Console.WriteLine($"用委托方法计算: 10 + 5 = {result1}"); // 2、使用匿名方法进行减法运算 //MathOperation operation2 = delegate (int a, int b) Func<int,int,int> operation2 = delegate (int a, int b)//内置Func { return a - b; }; int result2 = operation2(15, 7); Console.WriteLine($"用匿名方法计算: 15 - 7 = {result2}"); // 3、使用 Lambda 表达式进行乘法运算 //MathOperation operation3 = (a, b) => a * b;//委托变量 Func<int,int,int> operation3 = (a, b) => a * b;//内置Func int result3 = operation3(8, 6); Console.WriteLine($"用Lambda计算: 8 * 6 = {result3}"); Console.ReadKey(); } } 效果如下: 4、委托的BeginInvoke方法实现异步 委托的 BeginInvoke 方法和 EndInvoke 方法可以实现异步执行委托方法。这允许委托的方法在后台线程中执行,而不会阻塞当前线程。小编在之前的webform开发中遇到下载进度条卡死的问题就是用它解决的。 案例:
二、事件 事件对象之间的松耦合通信 1、事件的定义与声明 事件是委托的一种特殊应用,用于实现发布-订阅模型。使用event关键字可以声明事件,并指定事件委托的类型。事件允许对象通知其他对象在特定情况下执行操作,实现松耦合的通信机制。 //声名 public event TemperatureChangeHandler TemperatureChanged; 2、事件的订阅与发布 订阅事件的类(事件订阅者)可以将其方法绑定到事件上,以便在事件触发时执行操作。事件的持有者(事件发布者)在适当的时机触发事件,调用事件委托,从而通知所有订阅者执行相应的操作。 案例:
输出: 3、事件的安全性与封装 事件提供了一种封装机制,使得事件只能被持有者触发,而不会被外部随意调用。这样可以确保事件只在控制的范围内使用,增强代码的安全性和可维护性。 三、委托与事件的关系 using System; // 定义一个委托,用于处理温度变化事件 delegate void TemperatureChangeHandler(double temperature); // 温度监控类 class TemperatureMonitor { // 定义事件,将委托作为事件处理程序 public event TemperatureChangeHandler TemperatureChanged; private double currentTemperature; // 当前温度 // 属性,获取和设置当前温度,当温度发生变化时触发事件 public double CurrentTemperature { get { return currentTemperature; } set { if (value != currentTemperature) { currentTemperature = value; OnTemperatureChanged(value); // 温度变化时调用事件 } } } // 触发温度变化事件的方法 protected virtual void OnTemperatureChanged(double temperature) { TemperatureChanged?.Invoke(temperature); // 调用事件处理程序 } } class Program { static void Main(string[] args) { TemperatureMonitor monitor = new TemperatureMonitor(); // 订阅温度变化事件,将方法 OnTemperatureChanged 作为事件处理程序 monitor.TemperatureChanged += OnTemperatureChanged; // 改变当前温度,触发事件 monitor.CurrentTemperature = 25.5; Console.ReadKey(); } // 温度变化事件处理程序 static void OnTemperatureChanged(double temperature) { Console.WriteLine($"温度变化 {temperature}°C"); } } //案例参考:C#委托事件-张子阳 效果如下: 以上代码示例使用了委托和事件,实现了观察者模式。观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,使得当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。在这个示例中,TemperatureMonitor 类充当了被观察者(发布者),Program 类中的 OnTemperatureChanged 方法充当观察者(订阅者) 结语 该文章在 2023/8/31 18:41:14 编辑过 |