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的产生,也要先明白焦点,什么是焦点.焦点 : 使浏览器能够区分用户输入的对象,当一个元素有焦点的时候,那么他就可以接收用户的输入. 我们可以通过一些方式给元素设置 ...
随机推荐
- TensorFlow 池化层
在 TensorFlow 中使用池化层 在下面的练习中,你需要设定池化层的大小,strides,以及相应的 padding.你可以参考 tf.nn.max_pool().Padding 与卷积 pad ...
- 20182019-acmicpc-asia-dhaka-regional F .Path Intersection 树链剖分
直接进行树链剖分,每次对路径区间内的所有点值+1,线段树进行维护,然后查询线段树的最大值的个数!!! 查询线段树区间最大值个数,可以先维护区间和,在维护区间最值,如果区间和等于区间最值乘以区间长度,那 ...
- @noi.ac - 489@ shuffle
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个长度为 n 的序列 s1,s2,-,sn,它有 2^n− ...
- hdu 4063 Aircraft (Geometry + SP)
Problem - 4063 几何加简单最短路. 题意是给出若干圆的圆心以及半径,求出从给出的起点到终点的最短路径的长度,可以移动的区域是圆覆盖到的任意一个位置. 做法是这样的,对圆两两求交点,用这些 ...
- HTML5--语法
一.标记方法 1.内容类型(ContentType)还是.text/html 2.声明:<!DOCTYPE html SYSTEM “about:legacy-compat”> 3.字符编 ...
- [C#] Parallel.For的线程数
Parallel.For会自动判断同时运行多少个线程,但你也可以进行干预. ParallelOptions可以设置Parallel.For最大的并发线程.缺省的最大线程数是CPU核数.这通常是不够多的 ...
- oracle merge into 新增或者修改
merge into sn_balance b1 using(select 'admin' as userid,1 as type1 from dual) b2 on(b1.userid=b2.use ...
- python深浅copy和赋值
Python直接赋值,浅copy和深copy的比较 基于引用和对象(python引用和对象分离) 总结: 直接赋值:a = b -->a,b两个引用指向相同的对象 浅copy:a为b的copy ...
- 从零开始学习Kafka
简介 kafka是一个分布式消息队列.具有高性能.持久化.多副本备份.横向扩展能力.生产者往队列里写消息,消费者从队列里取消息进行业务逻辑.一般在架构设计中起到解耦.削峰.异步处理的作用. Kafka ...
- H3C 出站包过滤工作流程