白骑士的C#教学进阶篇 2.3 委托与事件

在C#编程中,委托和事件是实现复杂功能的关键工具。委托用于封装方法,实现回调机制和异步操作。事件则是基于委托的高级抽象,用于实现发布-订阅模式,允许对象之间进行通信和协调。在本节中,将详细介绍委托的定义与使用、事件的定义与触发,以及事件处理与回调机制,帮助您掌握如何利用这些功能实现灵活的编程解决方案。

委托的定义与使用

委托是一个类型安全的函数指针,用于封装一个或多个方法。通过委托,可以将方法作为参数传递给其他方法,实现回调机制。

定义委托

复制代码
public delegate void MyDelegate(string message);

使用委托

cs 复制代码
using System;


public class Program
{
    // 定义委托类型
    public delegate void MyDelegate(string message);

    // 定义一个与委托匹配的方法
    public static void ShowMessage(string message)
    {
        Console.WriteLine("Message: " + message);
    }

    public static void Main(string[] args)
    {
        // 创建委托实例并绑定方法
        MyDelegate del = new MyDelegate(ShowMessage);

        // 调用委托
        del("Hello, World!");

        // 使用匿名方法
        MyDelegate del2 = delegate(string msg) {
            Console.WriteLine("Anonymous message: " + msg);
        };

        del2("Hello from anonymous method!");

        // 使用Lambda表达式
        MyDelegate del3 = (msg) => Console.WriteLine("Lambda message: " + msg);
        del3("Hello from Lambda!");
    }
}

在这个示例中,定义了一个'MyDelegate'委托类型,并展示了如何使用命名方法、匿名方法和Lambda表达式来调用委托。

事件的定义与触发

事件是基于委托的一种特殊成员,用于实现发布-订阅模式。事件可以让一个类向其他类通知发生的动作,而无需了解订阅者的实现细节。

定义事件

cs 复制代码
public class Publisher
{
    // 定义一个委托
    public delegate void MyEventHandler(string message);

    // 定义一个事件
    public event MyEventHandler MyEvent;

    // 触发事件的方法
    public void RaiseEvent(string message)
    {
        if (MyEvent != null)
        {
            MyEvent(message);
        }
    }
}

订阅和触发事件

cs 复制代码
using System;


public class Subscriber
{
    public void OnEventRaised(string message)
    {
        Console.WriteLine("Event received: " + message);
    }
}


public class Program
{
    public static void Main(string[] args)
    {
        Publisher publisher = new Publisher();
        Subscriber subscriber = new Subscriber();

        // 订阅事件
        publisher.MyEvent += subscriber.OnEventRaised;

        // 触发事件
        publisher.RaiseEvent("Hello, Event!");
    }
}

在这个示例中,'Publisher'类定义了一个事件'MyEvent','Subscriber'类订阅该事件,并在事件触发时接收通知。

事件处理与回调

事件处理通常涉及多个订阅者。通过事件处理,可以实现复杂的事件驱动系统,确保在事件发生时所有订阅者都能收到通知。

多播委托

委托可以绑定多个方法,当调用委托时,所有绑定的方法都会依次被调用。这称为多播委托。

cs 复制代码
using System;


public class Program
{
    // 定义委托类型
    public delegate void MyDelegate(string message);

    // 定义两个方法
    public static void ShowMessage1(string message)
    {
        Console.WriteLine("Message 1: " + message);
    }

    public static void ShowMessage2(string message)
    {
        Console.WriteLine("Message 2: " + message);
    }

    public static void Main(string[] args)
    {
        // 创建委托实例并绑定方法
        MyDelegate del = new MyDelegate(ShowMessage1);
        del += ShowMessage2;

        // 调用多播委托
        del("Hello, Multicast Delegate!");
    }
}

在这个示例中,'del'委托实例绑定了两个方法'ShowMessage1'和'ShowMessage2',当调用'del'时,这两个方法都会依次执行。

事件处理回调

事件处理回调是在事件触发后,回调方法执行的机制。可以在事件触发后执行一些特定操作,实现异步或同步的通知机制。

cs 复制代码
using System;


public class EventPublisher
{
    public event EventHandler<EventArgs> OnChange;

    public void RaiseEvent()
    {
        OnChange?.Invoke(this, EventArgs.Empty);
    }
}


public class EventSubscriber
{
    public void Subscribe(EventPublisher publisher)
    {
        publisher.OnChange += HandleEvent;
    }

    private void HandleEvent(object sender, EventArgs e)
    {
        Console.WriteLine("Event handled.");
    }
}


public class Program
{
    public static void Main(string[] args)
    {
        EventPublisher publisher = new EventPublisher();
        EventSubscriber subscriber = new EventSubscriber();

        // 订阅事件
        subscriber.Subscribe(publisher);

        // 触发事件
        publisher.RaiseEvent();
    }
}

在这个示例中,定义了一个基于'EventHandler'的事件,'EventSubscriber'类订阅该事件,并在事件触发时处理回调。

总结

通过学习委托和事件的定义与使用、事件处理与回调机制,您掌握了在C#中实现回调、异步操作和发布-订阅模式的方法。委托提供了灵活的函数封装和调用机制,而事件则基于委托实现了对象之间的通知和通信。这些工具使得您的程序可以更加响应迅速,结构更加清晰。在接下来的章节中,您将继续探索C#的高级特性和编程技巧,进一步提升您的开发能力。

相关推荐
ss2731 分钟前
AI全栈实战 | 2.2-02 React 思维模型:数据不可变 vs Vue 数据可变,两种哲学把复杂度推给谁
前端·vue.js·react.js
想吃火锅10052 分钟前
【leetcode】189.轮转数组js
开发语言·javascript·leetcode
天衍四九-5 分钟前
Docker Compose企业实战系列(三):Vue/React前端项目容器化完整部署
前端·vue.js·docker
小小、码农11 分钟前
〖Linux进程间通信〗IPC全家桶:匿名管道、FIFO、共享内存、消息队列与信号量一篇打通
linux·运维·服务器
LaughingZhu12 分钟前
Product Hunt 每日热榜 | 2026-10-01
数据库·人工智能·深度学习·神经网络·搜索引擎
阳光九叶草LXGZXJ13 分钟前
达梦数据库-学习-67-SSL加密认证
linux·运维·数据库·sql·学习·ssl
掉进电商坑三年没爬出来的东叔17 分钟前
2026最新:青龙面板搭建全自动薅羊毛脚本,云服务器24小时挂机教程
运维·服务器·pygame
ha_lydms18 分钟前
MaxCompute中JSON函数
大数据·数据库·阿里云·json·dataworks·maxcompute·odps
Rosanci19 分钟前
从零到合入主线:我的 DeepSeek Harness 开源贡献实战手记
开发语言·前端·开源
用户9608198422327 分钟前
多周期联看时十字光标对不齐:前端排查「时间桶」的三步清单
前端