【C#基础教程】第二十章、事件

C# Events类和Event详解 C#中的 event 关键字,它与 System.Threading 名称空间中的 events 类没有关系。event 关键字基于委托,而上述 events 类是 .NET 封装器,用于系统范围内的本机事件资源的同步。通过事件使用委托事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模 阅读详情

目录

事件

1.事件

2.扩展EventArgs类


事件

1.事件

 事件的组成:事件由事件发布者和事件订阅者组成。事件内包含一个私有委托。

  • 当事件发布时,事件发布者会发布消息、而事件订阅者会接受到事件已发生的通知,并作出相应的处理。
    • 其中,触发事件的对象称为事件发布者,捕获事件并对其做出处理的对象称为事件订阅者。
具有一个事件的类的结构和术语

 

  事件的意义:很多程序都有同一种需求,当一个特定的程序事件发生时,程序的其他部分可以得到该事件已经发生的通知。

  • 发布者类定义了一系列程序的其他部分可能感兴趣的事件。其他类可以注册,以便在这些事件发生时收到发布者的通知。这些订阅者通过向发布者提供一个方法来注册以获得通知。当事件发生时,发布者触发事件,然后执行订阅者提供的所有事件。
  • 用生活中的事件举例:当我们听说哪里发生了某件事的时候,可能会对这件事采取某种措施。例如,我们看见宠物碗里没水了,我们需要向里面添加水。在C#中,我们看见宠物碗里没水了会被当成“事件”,而添加水则是对事件做出的响应。 

  事件的定义:事件建立在委托之上。且事件与定义类成员非常相似,仅需在其基础上使用event关键字即可。

  使用自定义委托类型定义事件的语法:

                访问修饰符 event 委托类型 事件名;

  使用.NET类库定义事件的语法:

                访问修饰符 event EventHandler 事件名;

  订阅事件的语法:

                发布者对象.事件名+=new 委托名(订阅者对象.处理事件方法名);

  取消订阅事件的语法:

                发布者对象.事件名-=new 委托名(订阅者对象.处理事件方法名);

  执行处理事件的语法:

                发布者对象.发出事件(参数);

   使用事件的要求:

  • 定义事件的访问修饰符一般为public。主要是为了方便事件订阅者进行订阅和取消操作
  • 委托类型既可以是自定义的委托类型,也可以是.NET类库中的EventHandler。

  使用事件: 

1.使用自定义委托类型定义事件

//宠物碗类,充当事件发布者
public class PetBowl
{
    //自定义委托
    public delegate void WaterHandler(string water);
    //使用自定义委托类型定义事件
    public event WaterHandler WaterEvent;
    
    //发出事件
    public void WaterDry(string water)
    {
        //判断是否绑定了事件处理方法
        if(WaterEvent!=null)
        {
            WaterEvent(water);
        }
    }
}
//主人类,充当事件订阅者
public class Master
{
    //字段
    public string Name;
    //构造函数
    public Master(string name)
    {
        Name = name;
    }
    //处理事件方法,该方法需要符合WaterHandler委托的定义
    public void FullWater(string water)
    {
        //对事件做出处理
        Console.WriteLine("{0}开始给宠物碗添加了{1}",this.Name,water);
    }
}
public class Program
{
    static void Main(string[] args)
    {
        //初始化宠物碗对象(事件发布者)
        PetBowl petBowl = new PetBowl();
        //实例化主人(事件订阅者)
        Master masterOne = new Master("憨憨一号");
        Master masterTwo = new Master("憨憨二号");
        Master masterThree = new Master("憨憨三号");

        //使用+=来订阅事件
        petBowl.WaterEvent+=new WaterHandler(masterOne.FullWater);
        petBowl.WaterEvent+=new WaterHandler(masterTwo.FullWater);

        //发出通知,此时只有订阅了事件的对象才能收到通知
        petBowl.WaterDry("牛奶");
        //使用+=来订阅事件
        petBowl.WaterEvent+=new WaterHandler(masterThree.FullWater);
        //使用-=来取消订阅事件
        petBowl.WaterEvent-=new WaterHandler(masterTwo.FullWater);
        //发出通知
        petBowl.WaterDry("水");
    }
}

2.使用.NET类库中的委托类型定义事件

//事件发布者
public class PetBowl
{
    //使用.NET类库中的委托类型定义事件
    public event EventHandler WaterEvent;
    //发布事件
    public void WaterDry(string water)
    {
        if(WaterEvent!=null)
        {
            //触发事件
            WaterEvent(this,new EventArgs(),water);
        }
    }
}
//事件订阅者
public class Master
{
    //字段
    public string Name;
    //构造函数
    public Master(string name)
    {
        Name=name;
    }
    //处理事件
    public void FullWater(object one,EventArgs e,string water)
    {
        Console.WriteLine("{0}向宠物碗中添加了{1}",this.Name,water);
    }
}
public class Program
{
    static void Main(string[] args)
    {
        //实例化事件发布者
        PetBowl petBowl=new PetBowl();
        //实例化事件订阅者
        Master masterOne = new Master();
        Master masterTwo = new Master();
        //订阅事件
        petBowl.WaterEvent += new EventHandler(masterOne.FullWater);
        petBowl.WaterEvent += new EventHandler(masterTwo.FullWater);
        //取消订阅事件
        petBowl.WaterEvent -= new EventHandler(masterTwo.FullWater);

        //触发事件
        petBowl.WaterDry("水");
    }
}

2.扩展EventArgs类

        当我们使用.NET类库中的委托类型定义事件时,我们会发现EventHandler只用于处理不包含事件数据的事件。如果我们想用这种定义方式的同时,还使事件包含事件数据,那我们可以通过派生EventArgs类来实现。

//自定义事件,并使其带有事件数据
public class WaterEventHandler:EventArgs
{
    public string Message;
    public WaterEventHandler(string msg)
    {
        Message=msg;
    }
}

Pi0 项目复现及项目问题解决方案(全网抢先发布~) 阅读详情

相关推荐

IBTrACS v04r01 数据提取实战:Pandas 筛选 JTWC/CMA/JMA 3机构最佳路径数据

本文详细介绍了如何使用 Pandas 高效提取和处理 IBTrACS v04r01 数据集中的最佳路径数据,特别针对 JTWC、CMA 和 JMA 三家权威机构的数据进行对比分析。通过构建可复用的数据提取函数,解决多机构数据质量差异问题,并提供高级分析与可视化应用示例,助力热带气旋研究。

clijovtbq401783153的博客 515

C#中的事件的使用 event

事件的使用 1 定义事件 public event 委托类型 事件名 2 注册事件 事件对象.事件 += 响应方法 3 触发事件 触发事件在类内部触发,事件定义在哪就在哪触发 4 调用事件 事件是一种观察者设计模式,如图 我们来一道题,来熟悉 这里有三个对象 人, 老鼠, 猫。分别三个类 猫叫是事件源 人醒和老鼠跑是被绑定的事件 代码 using System; namespace EventDemo { public class Program { public st

有趣的博客 692

NVIDIA驱动装好了,Gazebo为啥还是卡?手把手教你用optirun搞定GPU加速

本文详细解析了NVIDIA驱动安装后Gazebo仍卡顿的原因,并提供三步精准诊断与GPU加速实战方案。通过optirun快速启用GPU加速,解决OpenGL与显示服务器的配置问题,显著提升仿真性能。适用于ROS、PX4等开发环境,帮助用户充分利用显卡性能。

weixin_30379531的博客 465

C# 深入理解事件(event)机制

事件作为类的成员,一般是通过事件向其他类或对象通知发生的相关事情。发送事件的类称为发布者,接收事件的类称为订阅者。发布者确定何时引发事件;订阅者确定对事件作出何种响应一个事件可以有多个订阅者。订阅者可以处理来自多个发行者的多个事件。没有订阅者的事件永远也不会引发。事件通常用于表示用户操作,例如单击按钮或图形用户界面中的菜单选项。当事件具有多个订阅者时,引发该事件时会同步调用事件处理程序。也可通过async/await达到异步调用事件的作用。

明月清风@的博客 6184

保姆级教程:用Java和HslCommunication库搞定三菱PLC数据读写(附完整代码)

本文提供了一份详细的Java与三菱PLC通信教程,通过HslCommunication库实现高效数据读写。内容涵盖环境配置、通信模式选择、数据类型操作、异常处理及性能优化,并附有完整代码示例,帮助开发者快速掌握工业自动化中的PLC数据交互技术。

weixin_28731223的博客 227

使用AI预测彩票的架构思路

彩票是随机的数字游戏,不要过度依赖AI,本文仅供娱乐研究

淘淘小窝 9407

C# 事件和委托的区别并说明

委托在这里再说一遍委托跟事件的简单定义(没有搜到特别准确的,都是大概定义,理解万岁)委托:delegate 是一种可用于封装命名或匿名方法的引用类型。委托类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。委托是一种动态调用方法的类型,属于引用型。委托是对方法的抽象和封装。委托对象实质上代表了方法的引用(即内存地址)委托允许将方法作为参数进行传递。委托可用于定义回调方法。委托可以把多个方法链接在一起。这样,在事件触发时可同时启动多个事件处理程序。委托签名不需要与方法精确匹配。事件。

hllyzms的博客 7662

备赛电赛学习硬件篇(二):电源板电路设计

1、输入接口要准备各种接口,如2p端子,锂电池接口,typec等,提供多种电源供电方案2、输出接口3、自由拓展。

m0_61022809的博客 3213

C#核心技术---事件(Event)

C#事件是用于实现发布-订阅模式的一种机制,允许对象在发生特定动作时通知其他一个或多个订阅者。基于委托,事件定义了如何触发通知及接收者的响应方式。通过event关键字声明,通常结合EventHandler或自定义委托使用。事件提供了一种松耦合的方式让对象间通信,广泛应用于GUI交互、异步操作完成通知等场景,促进代码的模块化和可维护性。

white_papers的博客 1769

【大模型工程局】告别单打独斗:手把手带你构建多智能体系统(MetaGPT 启示录)

想象一下,不再是只有一个全知全能的 AI,而是有一群各有所长、能够独立思考和行动的“智能体”(Agent)。它们生活在一个共同的环境中,可以相互交流、协作完成共同目标,也可能为了有限资源而相互竞争。这就是多智能体系统(MAS)的核心图景。MAS 的关键特征:自治性 (Autonomy):每个智能体都能独立感知环境、做出决策并执行动作,无需外部直接控制。交互性 (Interaction):智能体之间可以通过某种通信机制(显式或隐式)交换信息、协调行为。

高校图书馆高级系统架构师/研究馆员,推动高校AI从概念演示到可评审、可交付、可运维:路线图与立项评审、PoC交付、评测回归与上线运维(Baseline/Eval/Ops)。 1183

openclaw通俗入门系列6——记忆系统

记忆 = 智能体的笔记本,分长期(MEMORY.md)和每日(memory/日期.md)。只有写到文件里的才能记住!支持语义搜索(理解意思)+ 关键词搜索,还能自动在压缩前保存重要内容。

m0_60605453的博客 403

【读书笔记】C#高级编程 第二十章 诊断

(一)诊断概述 名称空间System.Diagnostics提供了用于跟踪、事件日志、性能测量以及代码协定的类。System.Diagnostics.Contracts名称空间中的类可以定义前提条件、后置条件和常量,它们不仅可以在运行期间检查,还可以使用静态的协定分析器检查。 (二)代码协定 前置条件列出了参数必须满足的要求,后置条件定义了返回数据必须满足的要求,常量定义了方法中变量必...

weixin_30827565的博客 94

【数字孪生与仿真技术】06:航天器系统建模与验证全流程实战:从多学科建模到数字孪生(附完整代码与工业案例)

摘要:航天器系统开发面临多学科耦合强、验证流程复杂、可靠性要求极高的挑战。本文基于MATLAB/Simulink平台,系统阐述航天器从多域建模、动力系统开发到任务验证的全流程技术框架。内容涵盖Modelica统一建模规范、光伏-电池联合供电系统仿真、基于模型的需求追溯方法、蒙特卡洛可靠性分析及硬件在环测试等核心技术,并结合James Webb太空望远镜电力系统案例,展示工业级应用实践。文中提供完整的Simulink模型代码、仿真结果及流程图,最后探讨数字孪生与AI增强技术在航天器在轨运维中的未来应用。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1373

《CLR Via C#(第三版)》 第二十章

第20章 异常和状态管理 20.8 指导原则和最佳实践 编译器将你写的代码放到try块内部,并自动将清理代码放到finally块中。 使用lock语句时,锁会在finally块中释放。 使用using语句时,会在finally块中调用对象的dispose方法。 使用foreach语句时,会在finally块中调用IEnumerator对象的Dispose方法。 定义析构器方法时,会在f

284

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

WP8.1学习系列(第二十章)——添加控件和处理事件

先决条件 添加控件 设置控件的名称 设置控件属性 创建事件处理程序 新控件 总结 相关主题 通过使用如按钮、文本框和组合框等控件,你可以创建应用的 UI。 下面将显示如何将控件添加到应用。处理控件时,你通常会使用此模式: 将控件添加到应用 UI。 设置控件的属性,如宽度、高度或前景色。 将代码连接到控件,从而使控制执行任务。 路线图:本...

weixin_30507269的博客 106

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C#学习笔记

C#学习笔记

xfeng20的博客 275

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

《C#4.0中文视频教程共20课完整版》下载

下面是学习资料下载列表,您可以点击这些文件名进行下载,如果不能下载,请查看下载帮助 [C#4.0中文视频教程].课程说明.rar 3.6MB ...

weixin_34348111的博客 1221

Design Patterns In Modern C++ 中文版翻译 第二十章 观察者模式

毫无疑问,本章中提供的代码是一个明显的例子,它过度思考和过度设计了一个超出大多数人想要实现的问题的方式。让我们回顾一下实现 Observer 时的主要设计决策:决定你希望你的 observable 传达什么信息。例如,如果你正在处理字段/属性更改,则可以包含属性名称。你还可以指定旧/新值,但传递类型可能会出现问题。你想让你的观察者成为tire class,还是你只需要一个虚函数列表?你想如何处理取消订阅的观察者?

weixin_42603425的博客 614

【WPF学习】第二十章 内容控件

  内容控件(content control)是更特殊的控件类型,它们可包含并显示一块内容。从技术角度看,内容控件时可以包含单个嵌套元素的控件。与布局容器不同的是,内容控件只能包含一个子元素,而布局容器主要愿意可以包含任意多个牵头元素。   正如前面所介绍,所有WPF布局容器都继承自抽象类Panel,该类提供了对包含多个元素的支持。类似地,所有内容控件都继承自抽象类ContentControl。...

技术研究中心 850

25.02.04 《CLR via C#》 笔记 13

第二十章 异常和状态管理

nameNOTbad的博客 745

第二十章:异步和文件I/O.(一)

图形用户界面具有一点点特性,具有深远的影响:必须按顺序处理用户对应用程序的输入。无论用户输入事件是来自键盘,鼠标还是触摸,每个事件必须由应用程序完全处理 - 直接或通过用户界面对象(如按钮或滑块) - 在应用程序获得下一个用户之前 - 来自操作系统的输入事件。经过一些反思后,这个限制背后的基本原理变得清晰,可能是一个例子:假设一个页面包含两个按钮,用户可以...

weixin_34023982的博客 90

《CLR via C#》读书笔记 之 目录导航

《CLR via C#》读书笔记 之 目录导航 2013-02-27 读书笔记是按书本章节按序写的,只摘录了个人认为比较重要,关系比较紧密的知识点。第4部分 核心机制 和第5部分 线程处理 等有时间再整理 CLR核心功能包括:内存管理,程序集加载,安全性,异常处理,以及线程同步。 第Ⅰ部分 CLR基础 第一章:《CLR via C#》读书笔记 之 CLR执行模型 第二章: 《CLR...

weixin_34319999的博客 64

第二十章:异步和文件I/O.(五)

没有任何警报两个DisplayAlert方法中较简单的方法返回一个Task对象。 它旨在向用户显示一些不需要响应的信息: Task DisplayAlert (string title, string message, string cancel) 通常,即使它没有返回任何信息,你也会想要使用这个更简单的DisplayAlert方法,特别是如果你需要在它...

weixin_33923148的博客 102

CLR Via C#还值得一读吗

1.前言如今已经是.Net8了,而CLR Via这本书则是.Net Framework4.5时代的产物,相隔了好几代。这本书到底值不值得一读呢?2.概述Via这本书目前能找到的就是第四版,2015年出版的,距今已经七八年了。这本书的作者是:Jeffrey Richter。他是Windows内核和.Net CLR双料级的高手。书是这样介绍他的:特别擅长授人以渔,能够以通俗易懂、条理清晰的方式将普通读...

dotNET跨平台 641
上一篇: 【C#基础教程】第十九章、委托
下一篇: 【C#基础教程】第二十一章、泛型
Ohrkaninchen
博客等级 码龄5年 18粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ohrkaninchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值