C#委托(delegate)与事件(event)

25 年 4 月 10 日 星期四
958 字
5 分钟

基本概念梳理

委托 (delegate) 是一种基于类的数据类型,功能类似于C++中的函数指针。该类型用于表示对于具有特定参数列表返回类型的方法的引用。通俗来说,委托可以理解为持有一个或多个方法的对象。如果执行委托的话,委托会执行它所"持有"的方法。委托可以提高程序的可扩展性与灵活性。

本质上来看委托和相似,都是一种用户自定义的类型。不过类表示的是数据方法的集合,而委托则持有一个或多个方法,以及一系列预定义的操作。


事件 (event) 是基于委托的进一步封装,在使用上可以将它视作一个委托类型的变量。在用事件进行封装后,用户对于委托链上方法的操作权限受到适当的限制,用户只能够通过+=-=操作符来进行外部方法的注册注销,而不能使用=操作符来对委托进行直接赋值。增强了后续编码时的安全性。


相关要点

匿名方法与Lambda表达式

匿名方法是没有命名标识的方法,通常用于直接创建委托实例,而无需先定义一个独立的命名方法。它可以直接作为委托类型参数的一段代码,从而简化了“先声明方法,再传递给委托”的步骤。而Lambda表达式基本可以看作是匿名方法的另一种写法,其主要优势在于提供了更简洁的语法来定义委托实例。详见 DWHITE/3_编程与开发/CS/CSharp_Lambda表达式

注意 两者都是用于配合委托(事件)使用的子概念,可以说没什么好深究的

cs
Fun<int, int> anon = delegate(int i) {
	return ++i;
}

内置委托:ActionFunc

内置委托有:

  • Action:接受 0 到 16 个参数,用于没有返回值的方法;适合只需要“执行”操作的场景。
  • Func:接受 0 到 16 个参数,用于有返回值的方法,最后一个泛型参数为返回值类型;适合需要运算或计算结果后返回值的场景。
  • Predicate:用于判断条件的方法;返回布尔值,多用于集合过滤、查找等。
  • EventHandler:专门用于事件处理,确保事件触发时包含发送者和事件数据。

其中Action相对常用,例如下面:

  • PrintMessage() 方法与 Action 委托的签名匹配(无参数、返回 void)。
  • 通过 Action action = PrintMessage; 把方法传给委托,然后调用 action() 来执行该方法。
cs
using System;

class Program
{
    static void Main()
    {
        // 将 PrintMessage 方法赋值给 Action 委托
        Action action = PrintMessage;
        // 调用委托,从而执行 PrintMessage 方法
        action();
    }

    // 定义一个无参数且无返回值的方法
    static void PrintMessage()
    {
        Console.WriteLine("Hello, Action!");
    }
}

多使用内置委托,而不是频繁定义新的委托

多播委托(委托链 / 链式委托)

即一个委托可以指向多个适配的方法。使用+=运算符可以将多个方法添加到委托中,使用-=运算符可以从委托中移除方法。在委托执行时,将按照方法的注册顺序依次调用。

附1:C#的委托与C++的函数指针相比

C#委托C/C++ 函数指针
存储内容对象实例+方法地址函数地址
对象绑定自带绑定对象实例需要手动处理指定
安全性类型安全,签名匹配,强类型检查类型安全弱
面向对象很面向对象,封装了方法及其对象实例更像是过程式编程风格

文章标题:C#委托(delegate)与事件(event)

文章作者:DWHITE

文章链接:https://dr9k69ai79.github.io/MyBlog/posts/csharp_委托delegate与事件event[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。