C#——委托与事件(一)

一、委托的详解

在 C# 中,委托(Delegate)是一个非常重要的概念,它是一种引用类型,用于封装方法,让方法可以像对象一样被传递和调用。委托是回调函数的基础,它为事件驱动编程、异步操作、高阶函数等提供了核心支持。

1. 什么是委托?

委托是一个类似于函数指针的类型,它可以持有对一个方法的引用。
与函数指针不同的是,委托是类型安全的,并且支持多播。

委托的声明

// 声明一个委托类型
public delegate void MyDelegate(string message);
  • MyDelegate 是一个委托类型。
  • 它表示任何返回类型为 void,参数为一个字符串的方法。

2. 委托的基本使用

示例:委托的声明和使用

using System;

class Program
{
    // 声明一个委托
    public delegate void PrintDelegate(string message);

    static void Main(string[] args)
    {
        // 创建一个委托实例,指向 Print 方法
        PrintDelegate printer = Print;

        // 调用委托
        printer("Hello, Delegates!");

        // 使用匿名方法赋值
        printer = delegate (string msg) { Console.WriteLine($"Anonymous: {msg}"); };
        printer("Hello from anonymous delegate!");

        // 使用 Lambda 表达式赋值
        printer = msg => Console.WriteLine($"Lambda: {msg}");
        printer("Hello from lambda!");
    }

    // 与委托签名匹配的方法
    static void Print(string message)
    {
        Console.WriteLine($"Print: {message}");
    }
}

【拓展】 printer = msg => Console.WriteLine($“Lambda: {msg}”);
这里的Lambda 表达式是怎么实现的

输出:

Print: Hello, Delegates!
Anonymous: Hello from anonymous delegate!
Lambda: Hello from lambda!

3. 委托的特点

类型安全
委托只能指向与其签名相匹配的方法(参数类型和返回值类型必须一致)。

多播支持
委托可以指向多个方法,调用时会依次执行这些方法。

可组合
使用 += 添加方法,-= 移除方法。

4. 多播委托

示例:多播委托

using System;

class Program
{
    public delegate void NotifyDelegate(string message);

    static void Main(string[] args)
    {
        NotifyDelegate notify = Method1;
        notify += Method2; // 添加 Method2
        notify += Method3; // 添加 Method3

        notify("Delegates can multicast!");

        notify -= Method2; // 移除 Method2
        notify("After removing Method2");
    }

    static void Method1(string message) => Console.WriteLine($"Method1: {message}");
    static void Method2(string message) => Console.WriteLine($"Method2: {message}");
    static void Method3(string message) => Console.WriteLine($"Method3: {message}");
}

输出:

Method1: Delegates can multicast!
Method2: Delegates can multicast!
Method3: Delegates can multicast!
Method1: After removing Method2
Method3: After removing Method2

上述多播委托 (Multicast Delegate) 的使用和执行过程解析

1. 代码中的委托定义

public delegate void NotifyDelegate(string message);
  • NotifyDelegate 是一个自定义的委托类型。
  • 它可以指向任何返回 void 且接收一个 string 参数的方法。

2. 多播委托赋值和组合

NotifyDelegate notify = Method1;
notify += Method2; // 添加 Method2
notify += Method3; // 添加 Method3
  • notify 是一个 NotifyDelegate 类型的变量。
  • 它最初指向 Method1。
  • 使用 += 操作符, Method2 Method3 添加到多播列表
    最终,notify 包含了三个方法:Method1 -> Method2 -> Method3。

3. 调用多播委托

notify("Delegates can multicast!");
  • 当调用 notify 时,所有已订阅的委托方法都会依次执行。
  • 输入的参数 message 会被依次传递给 Method1、Method2 和 Method3。

第一次调用的输出:

Method1: Delegates can multicast!
Method2: Delegates can multicast!
Method3: Delegates can multicast!

4. 移除方法

notify -= Method2; // 移除 Method2
notify("After removing Method2");
  • 使用 -= 操作符,将 Method2 从 notify 的多播列表中移除。
  • 现在,notify 包含的方法是:Method1 -> Method3。

第二次调用的输出:

Method1: After removing Method2
Method3: After removing Method2

5. 执行顺序
在多播委托中:

  • 方法按添加的顺序依次执行。
  • 如果其中某个方法抛出异常,默认情况下后续方法不会执行。

5. 委托的常用类型

在实际开发中,为了简化委托的使用,C# 提供了几个内置的委托类型:

1.Action

  • 无返回值。
  • 可接受 0-16 个参数。

完整执行流程总结
1.定义一个多播委托 notify。
2.添加 Method1、Method2 和 Method3 到委托。
3.调用 notify 时,依次执行:

  • Method1(“Delegates can multicast!”)
  • Method2(“Delegates can multicast!”)
  • Method3(“Delegates can multicast!”)

4.使用 -= 移除 Method2。
5.再次调用 notify,只执行 Method1 和 Method3。

优点

  • 多播:一个委托变量可以指向多个方法。
  • 动态管理:可以随时添加或移除方法。
  • 统一调用:只需要调用委托变量,无需单独调用多个方法。
Action<int, string> action = (num, str) => Console.WriteLine($"{num}, {str}");
action(42, "Hello");

2.Func

  • 有返回值。
  • 最后一个泛型参数为返回类型,其余为输入参数类型。
Func<int, int, string> func = (a, b) => (a + b).ToString();
Console.WriteLine(func(2, 3)); // 输出 "5"

3.Predicate

  • 返回 bool 类型。
  • 通常用于条件判断。
Predicate<int> isEven = n => n % 2 == 0;
Console.WriteLine(isEven(4)); // 输出 "True"

6. 委托与事件的关系

事件是基于委托实现的。事件可以看作是对委托的进一步封装,用于发布-订阅模式。

事件与委托的区别

  • 委托是方法的引用类型,可以直接调用。
  • 事件对委托进行了封装,只能在声明类中触发,而不能在外部直接调用。

事件的示例:

using System;

class Program
{
    public delegate void NotifyDelegate(string message);

    // 声明事件
    public event NotifyDelegate NotifyEvent;

    static void Main(string[] args)
    {
        var program = new Program();

        // 订阅事件
        program.NotifyEvent += msg => Console.WriteLine($"Received: {msg}");

        // 触发事件
        program.Notify("Hello, Events!");
    }

    public void Notify(string message)
    {
        NotifyEvent?.Invoke(message); // 触发事件
    }
}

7. 委托的应用场景

回调函数:异步操作的结果处理。
事件机制:用于发布-订阅模型。
策略模式:算法或逻辑的动态选择(如排序比较器)。
高阶函数:动态传递处理逻辑(如 LINQ)。
多播场景:通知多个订阅者(如广播消息)。

总结

委托是 C# 中非常强大的工具,用于封装方法,使其可以动态传递和组合。 委托是事件、回调函数、多播通知等核心机制的基础。 使用内置的
Action、Func、Predicate 类型,可以大幅简化委托的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值