当前位置: 首页 > article >正文

C#委托的概念与使用方法

一、委托的基本概念

  • 委托是一种引用类型,它允许将方法作为参数进行传递。简单来说,委托就像是对方法的引用,可以通过委托来调用对应的方法。

  • 委托具有类型安全性,它会检查方法的签名是否与委托的签名匹配,这有助于避免类型不匹配的错误。

二、委托的声明与使用 

  • 声明委托 :使用 delegate 关键字来声明一个委托,其语法形式为:[访问修饰符] delegate 返回类型 委托名 (参数列表); 。例如:public delegate int MyDelegate(int x, int y); ,这表示声明了一个名为 MyDelegate 的委托,它接受两个整型参数,并返回一个整型值。

  • 实例化委托 :要使用委托,首先需要实例化它。实例化委托时需要指定一个与委托签名匹配的方法。例如:

    public class Program
    {public static int Add(int a, int b){return a + b;}static void Main(string[] args){MyDelegate myDelegate = new MyDelegate(Add);int result = myDelegate(2, 3);Console.WriteLine(result);  // 输出 5}
    }

    在这个例子中,我们声明了一个委托 MyDelegate,然后定义了一个与委托签名匹配的方法 Add。在 Main 方法中,我们实例化了委托 myDelegate,并将其指向 Add 方法,最后通过委托调用了 Add 方法。

  • 匿名方法 :在实例化委托时,还可以使用匿名方法,即无需事先定义一个方法,而是在实例化委托时直接定义方法体。例如:MyDelegate myDelegate = delegate(int x, int y) { return x + y; };这种方式可以在某些简单场景下简化代码。

  • lambda 表达式 :lambda 表达式是匿名方法的更简洁的表示形式,它在语法上更加简洁直观。例如:MyDelegate myDelegate = (x, y) => x + y;这里的 (x, y) => x + y 就是一个 lambda 表达式,它表示接受两个参数 xy,并返回它们的和。

三、系统委托 

  • Action 委托System.Action 是一个无返回值的委托。它可以用于表示不返回任何结果的方法。例如:

    Action<string> printAction = s => Console.WriteLine(s);
    printAction("Hello, World!");

    这个例子中,Action<string> 表示一个接受一个字符串参数且无返回值的委托。我们通过 lambda 表达式定义了 printAction 委托,使其将接收到的字符串打印到控制台。

  • Func 委托System.Func 是一个有返回值的委托。它可以用于表示返回特定类型结果的方法。例如:

    Func<int, int, int> addFunc = (a, b) => a + b;
    int result = addFunc(2, 3);
    Console.WriteLine(result);  // 输出 5
  • Predicate 委托System.Predicate 是一个返回布尔值的委托。它通常用于表示判断条件的方法。例如:

    List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
    Predicate<int> isEven = n => n % 2 == 0;
    List<int> evenNumbers = numbers.FindAll(isEven);
    foreach (int num in evenNumbers)
    {Console.WriteLine(num);  // 输出 2 和 4
    }

    在这个例子中,Predicate<int> 表示一个接受一个整型参数并返回一个布尔值的委托。我们通过 lambda 表达式定义了 isEven 委托,使其判断一个整数是否为偶数。然后使用 FindAll 方法将列表中满足条件的元素筛选出来。

四、事件委托 

  • 概念 :事件是基于委托的一种特殊应用,用于在对象之间传递消息。事件委托是定义事件的基础,它规定了事件处理程序的方法签名。

  • 声明事件委托 :通常,事件委托的声明需要结合特定的参数类型,如 EventArgs 及其派生类。例如:public delegate void EventHandler(object sender, EventArgs e);这是 .NET 中一个常见的事件委托声明,其中 sender 表示事件源,e 包含事件相关的数据。

  • 声明事件 :在类中使用 event 关键字来声明事件。例如:

    public class Button
    {public event EventHandler Click;// 其他代码
    }

    在这个例子中,Button 类声明了一个名为 Click 的事件,它基于 EventHandler 委托。

  • 引发事件 :在适当的时候(如用户点击按钮时),调用事件来通知订阅者。在引发事件时,通常需要创建一个事件数据对象作为参数传递。例如:

protected virtual void OnClick(EventArgs e)
{Click?.Invoke(this, e);
}

OnClick 方法用于引发 Click 事件。使用 Click?.Invoke(this, e); 的方式可以安全地调用事件,避免事件为 null 时引发异常。

  • 订阅事件 :其他对象可以通过注册事件处理程序来订阅事件。例如:

    Button button = new Button();
    button.Click += Button_Click;void Button_Click(object sender, EventArgs e)
    {// 处理按钮点击事件的逻辑
    }

    在这段代码中,我们创建了一个 Button 对象,并通过 += 运算符将 Button_Click 方法订阅到 Click 事件上。当按钮被点击时,Button_Click 方法将被调用。

  • 解除订阅 :在不需要再接收事件通知时,可以使用 -= 运算符来解除订阅。例如:button.Click -= Button_Click;

五、委托的多播 

  • 概念 :委托可以将多个方法组合在一起,形成一个调用链,这就是委托的多播特性。当调用多播委托时,它会按照添加的顺序依次调用所有组合的方法。

  • 示例

    public class Program
    {public static void Method1(){Console.WriteLine("Method1 called");}public static void Method2(){Console.WriteLine("Method2 called");}static void Main(string[] args){Action action1 = Method1;Action action2 = Method2;Action multiCastDelegate = action1 + action2;multiCastDelegate();// 输出:// Method1 called// Method2 called}
    }

    在这个例子中,我们创建了两个 Action 委托 action1action2,它们分别指向 Method1Method2 方法。然后通过 + 运算符将它们组合成一个多播委托 multiCastDelegate。当调用 multiCastDelegate 时,Method1Method2 会依次被执行。

六、总结 

C# 中的委托是一种强大的机制,它允许将方法作为参数进行传递,并且具有类型安全性。系统委托如 ActionFuncPredicate 提供了方便的预定义委托类型,可以用于各种常见的场景。事件委托则是委托在事件驱动编程中的特殊应用,用于解耦事件源和事件处理者。委托的多播特性使得可以将多个方法组合在一起形成调用链,提供了更大的灵活性。

通过合理使用委托,可以使代码更加模块化、灵活和可维护。

http://www.lryc.cn/news/2399022.html

相关文章:

  • 消费者行为变革下开源AI智能名片与链动2+1模式S2B2C商城小程序的协同创新路径
  • 软考 系统架构设计师系列知识点之杂项集萃(78)
  • 解决MyBatis参数绑定中参数名不一致导致的错误问题
  • 如何解决MySQL Workbench中的错误Error Code: 1175
  • Docker 镜像(或 Docker 容器)中查找文件命令
  • MySQL进阶篇(存储引擎、索引、视图、SQL性能优化、存储过程、触发器、锁)
  • python批量解析提取word内容到excel
  • BugKu Web渗透之game1
  • 使用Composer创建公共类库
  • Axure设计案例——科技感渐变柱状图
  • LeetCode 热题 100 394. 字符串解码
  • 互联网大厂智能体平台体验笔记字节扣子罗盘、阿里云百炼、百度千帆 、腾讯元器、TI-ONE平台、云智能体开发平台
  • 深入解析ReactJS中JSX的底层工作原理
  • 亡羊补牢与持续改进 - SRE 的安全日志、审计与事件响应
  • NodeMediaEdge任务管理
  • LIMIT 和 OFFSET 在大数据量下的性能问题分析与优化方案
  • SpringBoot集成第三方jar的完整指南
  • 登高架设作业实操考试需要注意哪些安全细节?
  • 前端基础之《Vue(18)—路由知识点》
  • 014校园管理系统技术解析:构建智慧校园管理平台
  • 微服务各个部分的作用
  • SQLite详细解读
  • LRC and VIP
  • Python趣学篇:Pygame重现经典打砖块游戏
  • 电脑硬盘分几个区好
  • Vue3 + Element Plus + TypeScript 中 el-cascader 实现模拟用户点击功能
  • 【java】springboot注解关键字
  • supervisor 常见问题大全
  • 2024 CKA模拟系统制作 | Step-By-Step | 18、题目搭建-备份还原Etcd
  • 【Netty系列】Reactor 模式 2