C# event 事件-2
本次是对第一篇事件随笔的补充笔记,涉及题目依然使用上一篇的习题。上一篇地址:https://www.cnblogs.com/FavoriteMango/p/11685702.html
1.事件的定义
事件的定位可以参考属性,C#中,属性是对字段的封装,相对而言,基于委托来声明的事件也是对委托的封装,但是属性≠字段,同样事件≠委托。至于为何封装,可另行查阅文档。
2.事件的简要声明和详细声明
通常的学习案例中大部分对事件的使用都是通过简要声明(语法糖)的方式使用的,包括上一篇随笔中我初学事件时的例子,但这次有接触到事件声明的详细流程。
事件的简要声明中省略了对委托字段的声明步骤,由于Action和Fun这两个委托类,你甚至可以完全不声明委托类型,并且由于语法糖,你可能会把委托和事件完全混淆,这是错误的。
事件的详细声明需要有对委托类型的定义,事件参数的定义,委托字段的定义,还有事件本身的定义,对事件的定义中还有add和remove关键字以及相关逻辑的处理(add和remove可以用属性的get、set的定义来参考),强烈建议通过详细的声明流程来理解事件。
3.定义事件时需要的一些参数
虽然没有硬性规定事件必须要有哪些参数,但所有事件基于情理最好有两个参数,第一个是事件的发起者,第二个是事件所包含的相关信息。参考Winform,所有的事件都有sender和e两个参数,他们分别对应发起者和信息。
在这里C#将sender定义为Object,也给出了基本的信息类(EventArgs类),而自定义的信息类都要继承EventArgs类,并且在定义类的时候类名都要加EventArgs为后缀(例如后面的AnimalEventArgs),这是一种命名规范。
4.其他一些要注意的地方
声明委托类型时,要注意同为数据类型的委托是和类(class)平级的存在,它应当(但不绝对)声明在和类平级的命名空间里。
简要声明是一种语法糖,它简化了了事件的使用流程,但是也容易混淆概念,在下面的代码中请重点注意在事件的发起者中对于事件的定义和事件的触发两处的代码。
5.习题部分
回到习题,依然是开枪的事件,首先是事件的相关参数的定义,包括委托类型的定义,事件信息类的定义:
//声明委托类型
//Parson : 事件发起者的类
public delegate void FireEventHandler(Parson parson, FireEventArgs e); /// <summary>
/// 事件参数中的信息类
/// </summary>
public class FireEventArgs : EventArgs
{
public Animal Animal { get; set; }
}
然后是事件的发起者和订阅者
/// <summary>
/// 事件的发起者
/// </summary>
public class Parson
{
//委托类型的字段
private FireEventHandler fireEventHandler; //封装委托类型的事件
public event FireEventHandler Fire
{
add
{
//添加事件处理器
//value:在订阅事件时添加的事件处理器
this.fireEventHandler += value;
}
remove
{
//移除事件处理器
this.fireEventHandler -= value;
}
} public string Name { get; set; } public void OnFire(FireEventArgs e)
{
Console.WriteLine("{0}正在开枪。", Name); if (fireEventHandler != null)
{
//触发事件
fireEventHandler.Invoke(this, e);
}
}
} /// <summary>
/// 事件的订阅者
/// </summary>
public class Animal
{
public string Name { get; set; } internal void Action(Parson sender, FireEventArgs e)
{
Console.WriteLine("由于" + sender.Name + "开枪," + e.Animal.Name + "受到了惊吓。"); if (e.Animal.Name == "鸟") { Console.WriteLine(e.Animal.Name + "飞了"); } } }
最后是订阅事件
class Program
{
static void Main(string[] args)
{
//人开枪,鸟飞了
//事件拥有者:人
//事件本身:开枪
//事件响应者:鸟
//事件处理:飞了
//订阅关系:鸟 → 开枪
//事件的完整声明 Parson parson = new Parson { Name = "Your name" }; Animal animal = new Animal { Name = "Animal name" }; parson.Fire += animal.Action; parson.OnFire(new FireEventArgs { Animal = animal });
}
}
把Animal的name属性赋值为“鸟”
class Program
{
static void Main(string[] args)
{
//人开枪,鸟飞了
//事件拥有者:人
//事件本身:开枪
//事件响应者:鸟
//事件处理:飞了
//订阅关系:鸟 → 开枪
//事件的完整声明 Parson parson = new Parson { Name = "Your Name" }; Anime anime = new Anime { Name = "鸟" }; parson.Fire += anime.Action; parson.OnFire(new FireEventArgs { Anime = anime });
}
}
运行可得结果:
C# event 事件-2的更多相关文章
- [.NET] C# 知识回顾 - Event 事件
C# 知识回顾 - Event 事件 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6060297.html 序 昨天,通过<C# 知识回顾 - ...
- Event事件
妙味课堂-Event事件 1.焦点:当一个元素有焦点的时候,那么他就可以接受用户的输入(不是所有元素都能接受焦点) 给元素设置焦点的方式: 1.点击 2.tab 3.js 2.(例子:输入框提示文字) ...
- JS学习笔记9之event事件及其他事件
-->鼠标事件-->event事件对象-->默认事件-->键盘事件(keyCode)-->拖拽效果 一.鼠标事件 onclick ---------------鼠标点击事 ...
- JS(event事件)
常用的event事件: 属性 此事件发生在何时... onabort 图像的加载被中断. onblur 元素失去焦点. onchange 域的内容被改变. onclick 当用户点击某个对象时调用的事 ...
- event事件学习小节
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Javascript 事件对象(二)event事件
Event事件: <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" ...
- js event 事件兼容浏览器 ie不需要 event参数 firefox 需要
js event 事件兼容浏览器 ie不需要 event参数 firefox 需要 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...
- PHP event 事件机制
PHP event 事件机制 <?php /* * PHP 事件机制 */ class baseClass{ private $_e; public function __set($name ...
- trigger()的event事件对象之坑
问题引入,先贴一段有问题的代码,如果你对 trigger() 这个函数了解不透彻,还真看不出这段代码错在哪.完成的功能是样式转换器,想让页面在加载后自行触发点击事件隐藏三个按钮,但是效果如图并没有隐 ...
- Event事件详解
首先提到event,先要明白event的产生,也要先明白焦点,什么是焦点.焦点 : 使浏览器能够区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入. 我们可以通过一些方式给元素设置 ...
随机推荐
- maven 从svn导入项目遇到的问题 No marketplace entries found to handle yuicompressor maven plugin:1.3.0:compile
版权声明:本文为博主原创文章,未经博主同意不得转载.安金龙 的博客. https://blog.csdn.net/smile0198/article/details/25463825 RT.使用ecl ...
- mysql中时间字段datetime怎么判断为空和不为空
mysql中时间字段datetime怎么判断为空和不为空一般为空都用null表示,所以一句sql语句就可以.select * from 表名 where 日期字段 is null;这里要注意null的 ...
- AbstractExecutorService的submit方法概要介绍
1.概述 ExecutorService是JDK提供的框架,它简化了异步模式下的任务执行.一般来说,ExecutorService会自动提供一个线程池和API,用于为其分配任务. 2.实例化Execu ...
- 阿里云POLARDB 2.0重磅来袭!为何用户如此的期待?
点击报名:POLARDB 2.0 升级发布会 回顾POLARDB 1.0升级之路 POLARDB 1.0主要的改进包括采用了计算存储分离的架构,完全兼容MYSQL,性能是原生MySQL的6倍.一个用户 ...
- 前后端登录注册之node剖析与token的使用状态
登录模块功能详解 1.用户名密码的格式验证 由前端完成,根据需求自行决定,不加叙述 2.点击提交按钮思路详解 前端将用户名 以及加密后的密码还有验证码输入的内容统一发给后端 由后端和数据库的数据进行 ...
- 亿级消息系统的核心存储:Tablestore发布Timeline 2.0模型
背景 互联网快速发展的今天,社交类应用.消息类功能大行其道,占据了大量网络流量.大至钉钉.微信.微博.知乎,小至各类App的推送通知,消息类功能几乎成为所有应用的标配.根据场景特点,我们可以将消息类场 ...
- 多版本python共存,安装三方库到指定python版本
多版本python安装过程略过不提提供完美解决python启动和各版本pip问题: python3下pip安装命令如下: py -3 -m pip install xxxxxx python2下pip ...
- H3C用Telnet登录
- jq获取单选框、复选框、下拉菜单的值
1.<input type="radio" name="testradio" value="jquery获取radio的值" /> ...
- [转]Node.js中package.json中^和~的区别
webpack 项目的package.json 文件列出了项目所依赖的插件和库,同时也给出了对应的版本说明,但是在版本说明前面还有个符号:'^'(插入符号)和'~'(波浪符号),总结了下他们之间的区别 ...