博客
关于我
委托和事件
阅读量:480 次
发布时间:2019-03-06

本文共 2650 字,大约阅读时间需要 8 分钟。

事件与委托是C#编程中的两个核心概念,它们允许代码之间以松散的方式进行通信,而不需要直接调用彼此的方法。传统的编程方式通常是同步代码,方法之间直接调用,这种耦合度很高且难以维护。事件和委托则提供了一种更灵活的通信方式,适用于需要多路广播或异步处理的场景。

事件与委托的基本概念

事件和委托的主要作用是实现松耦合的方法调用。委托类似于函数的定义方式,但不包含方法体,仅用于定义接收事件的目标函数。事件则是可以触发的动作,通过委托传递给其他对象处理。

事件与委托的实际应用

让我们通过一个实际的例子来理解事件与委托的使用。假设我们有一个公司,公司里有董事长(Admin)、经理(Manager)和雇员(Employee)。董事长希望监控雇员在上班时间是否玩游戏,但他不想一直盯着每个雇员。

  • 定义委托类型

    首先,我们定义一个委托类型DelegateClassHandle,用于传递事件。这个委托接受两个参数:事件发送者(sender)和事件数据(e)。

  • 雇员类(Employee)

    雇员类中,我们定义了一个事件PlayGame,事件的类型是DelegateClassHandle。这个事件会在雇员开始玩游戏时被触发。

  • 董事长类(Admin)

    董事长类中,我们定义了一个方法Notify,它会接收事件并输出相应的信息。这个方法会被注册为事件的目标函数。

  • 事件绑定

    通过在雇员的PlayGame事件上添加委托,我们可以将事件关联到董事长的Notify方法。这样,当雇员玩游戏时,事件会自动通知董事长。

  • 扩展到多路广播

    如果我们有多个需要接收通知的对象(如经理),只需为每个对象注册一个委托即可。事件可以同时通知多个对象,这种机制称为多路广播(Mulitcast)。

  • 事件参数的扩展

    为了更好地传递数据,我们可以定义一个自定义的事件参数类CustomeEventArgs。这个类可以携带雇员的名字和年龄信息。

  • 委托的灵活性

    委托允许事件传递任意类型的参数,并且可以通过+=-=操作符进行动态绑定和解除绑定。这种方式使得代码更加灵活和可维护。

  • 优化后的代码示例

    public delegate void DelegateClassHandle(object sender, CustomeEvetnArgs e);public class Employee{    private string _name;    private int _age;    public string Name    {        get => _name;        set => _name = value;    }    public int Age    {        get => _age;        set => _age = value;    }    public event DelegateClassHandle PlayGame;    public void Games()    {        if (PlayGame != null)        {            var e = new CustomeEvetnArgs();            e.Name = _name;            e.Age = _age;            PlayGame(sender: this, e);        }    }}public class Admin{    public void Notify(object sender, CustomeEvetnArgs e)    {        Console.WriteLine($"{e.Name} is {e.Age}");    }}public class Manager{    public void Notify(object sender, CustomeEvetnArgs e)    {        Console.WriteLine($"{sender.ToString()} - {e.Name}");    }}public class CustomeEvetnArgs : EventArgs{    public string Name { get; set; }    public int Age { get; set; }    public CustomeEvetnArgs()    {    }}

    代码解释

  • 委托定义

    使用delegate关键字定义一个委托类型DelegateClassHandle,它接受两个参数:sender(事件发送者)和e(事件参数)。

  • 雇员类

    • 定义两个私有字段 _name_age,用于存储雇员的信息。
    • 定义两个公共属性 NameAge,用于获取和设置雇员的名字和年龄。
    • 定义一个事件 PlayGame,类型为DelegateClassHandle
    • 实现方法 Games(),在触发事件前创建一个CustomeEvetnArgs对象,并设置事件参数,然后调用事件。
  • 董事长类

    • 定义一个方法 Notify,它接收事件发送者和事件参数,并输出相应的信息。
  • 经理类

    • 定义一个方法 Notify,它接收事件发送者和事件参数,并输出发送者的信息和事件参数的名字。
  • 自定义事件参数类

    • 定义一个EventArgs派生类CustomeEvetnArgs,它包含两个属性 NameAge,用于传递雇员的信息。
  • 代码示例

    • 创建一个Employee对象,并设置其名字和年龄。
    • 创建一个Admin对象和一个Manager对象。
    • EmployeePlayGame事件上添加一个委托,将事件关联到AdminNotify方法。
    • 如果需要,可以为Manager也注册一个委托。
    • 调用EmployeeGames()方法,触发事件并传递数据。
  • 注意事项

    • 事件绑定

      在调用Games()方法前,确保PlayGame事件不为null,否则会抛出NullReferenceException异常。

    • 多路广播

      事件可以同时通知多个对象,只需为每个对象注册一个委托即可。

    • 动态绑定

      使用+=操作符注册委托,可以动态地添加或移除事件处理方法。

    通过这种方式,事件和委托实现了松耦合的通信方式,使得代码结构更加清晰,耦合度降低,易于扩展和维护。

    转载地址:http://jftbz.baihongyu.com/

    你可能感兴趣的文章
    NodeJs单元测试之 API性能测试
    查看>>
    nodejs图片转换字节保存
    查看>>
    NodeJs学习笔记001--npm换源
    查看>>
    nodejs配置express服务器,运行自动打开浏览器
    查看>>
    Node入门之创建第一个HelloNode
    查看>>
    Node出错导致运行崩溃的解决方案
    查看>>
    node安装及配置之windows版
    查看>>
    Node提示:error code Z_BUF_ERROR,error error -5,error zlib:unexpected end of file
    查看>>
    NOIp2005 过河
    查看>>
    NOPI读取Excel
    查看>>
    NoSQL&MongoDB
    查看>>
    NotImplementedError: Cannot copy out of meta tensor; no data! Please use torch.nn.Module.to_empty()
    查看>>
    npm install digital envelope routines::unsupported解决方法
    查看>>
    npm install报错,证书验证失败unable to get local issuer certificate
    查看>>
    npm install无法生成node_modules的解决方法
    查看>>
    npm run build 失败Compiler server unexpectedly exited with code: null and signal: SIGBUS
    查看>>
    npm run build报Cannot find module错误的解决方法
    查看>>
    npm run build部署到云服务器中的Nginx(图文配置)
    查看>>
    npm run dev 报错PS ‘vite‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。
    查看>>
    npm start运行了什么
    查看>>