Overview

在前几章,我们已经对委托有了一个完整的了解了,本章将会对事件进行一下介绍:

相对于委托,事件再是我们更加频繁的接触的,比如 鼠标的click 事件,键盘的 keydown 事件等等。

事件的特点:

  • 只能进行 += 或者 -= 操作
  • 只能在,定义事件的类的内部调用事件,在其他类中不能调用

大家还记不记得学面向对象的时候,对属性是怎么描述的

对字段的封装,为了保护字段!

那么,事件之于委托,也是同样的目的, 对委托的封装,为了保护委托

我们在写代码的时候,一直会遵循这么一个规范: 永远不要经字段暴露出来! ,那么委托同样是这样能的,至于为什么这样,下文会有详细的介绍。

Event的语法

使用事件就要用到 event 关键字,并且事件是对委托的封装,有了委托才能有事件。

  1. 定义一个委托
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace UnderstandDelegate
{
public delegate void SimpleHandler();
}
  1. 将委托封装为事件
public event SimpleHandler SimpleEvent;

为什么要引入事件

为什么要引入属性的概念? 因为,将字段暴露出来不安全. 为什么引入事件,因为将委托暴露出来不安全。让我们来看一看为什么是这样。

  1. 定义一个委托
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace UnderstandDelegate
{
public delegate void SayHelloHandler();
}
  1. 建立一个Person类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace UnderstandDelegate
{
public class Person
{
public SayHelloHandler sayHelloHandler; public void SayHello()
{
if (sayHelloHandler != null)
sayHelloHandler.Invoke();
}
}
}
  1. 调用Person类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace UnderstandDelegate
{
class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.sayHelloHandler += ChinaStyleSayHello;
person.sayHelloHandler += EnglishStyleSayHello;
} static void ChinaStyleSayHello()
{
Console.WriteLine("你好");
} static void EnglishStyleSayHello()
{
Console.WriteLine("Hello");
} static void JapanStyleSayHello()
{
Console.WriteLine("坑你急哇");
}
}
}

上面的代码,没有问题,是的确实是这样,如果没有意外的话。 请注意,我将犯一些致命的错误:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace UnderstandDelegate
{
class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.sayHelloHandler += ChinaStyleSayHello;
person.sayHelloHandler += EnglishStyleSayHello;
//错误在这里,将之前赋值给委托的方法清空了
person.sayHelloHandler = null;
person.sayHelloHandler += JapanStyleSayHello;
} static void ChinaStyleSayHello()
{
Console.WriteLine("你好");
} static void EnglishStyleSayHello()
{
Console.WriteLine("Hello");
} static void JapanStyleSayHello()
{
Console.WriteLine("坑你急哇");
}
}
}

这还得了,如果说,因为你的一时疏忽,出现了上面的操作,如果说这个情况,是在一个大型的程序中,这种情况可是很致命的!

还有这种情况

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace UnderstandDelegate
{
class Program
{
static void Main(string[] args)
{
Person person = new Person();
person.sayHelloHandler += ChinaStyleSayHello;
person.sayHelloHandler += EnglishStyleSayHello;
//错误在这里,将之前赋值给委托的方法清空了
person.sayHelloHandler = null;
person.sayHelloHandler += JapanStyleSayHello;
//在Person类的外部,调用的Person类内部的委托
person.sayHelloHandler();
} static void ChinaStyleSayHello()
{
Console.WriteLine("你好");
} static void EnglishStyleSayHello()
{
Console.WriteLine("Hello");
} static void JapanStyleSayHello()
{
Console.WriteLine("坑你急哇");
}
}
}

这用情况,就更致命了,想象这么一个场景: 如果我们做了一个金融方面的项目,这项目中涉及到了资金的流转等敏感操作,恰恰这个操作,是交给一个委托来执行的,如果我们出现了这么一个情况,在不在调用的时候,自己手动调用了委托,那么,请做好老板找你谈话的准备吧。

这些问题都可以用事件来解决

我们需要对Person类,进行一下简单的修改。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace UnderstandDelegate
{
public class Person
{
//将委托封装为了事件
public event SayHelloHandler sayHelloHandler; public void SayHello()
{
if (sayHelloHandler != null)
sayHelloHandler.Invoke();
}
}
}

我们在看一下原来的代码

根本就不会被编译,那么这样就从根源上解决了我们使用委托,可能出现的高风险的问题。因为他根本就不让你编译,必须修改了才行![img](file:///C:\Users\IT\AppData\Local\Temp\SGPicFaceTpBq\19984\B10103B6.png)。

结语

可能,刚刚接触委托和事件的时候,刚刚回被这两个的概念搞得一脸懵逼,只需要记住: 事件是对委托的封装 即可。最后,希望本文可以帮助到各位看官。

文中有任何纰漏之处还望指出,以免笔者,误人误己,在此拜谢。

理解事件(Event)的更多相关文章

  1. 深入理解事件(Event)

    前言 在前一篇文章中讲到了Event 发布与订阅(一) 里面用到了事件来实现一些发布与订阅,当时对事件及其委托理解的还不是太深入,可能在使用上有点捉急.这篇来好好讲讲事件,以及通过一些小DEMO来加深 ...

  2. 深入理解事件(event)与委托(delegate)

    好久没学.NET了,最近重又开始学习,发现委托有很多变化了,发现事件不明白了(可能以前就没明白过) 网上搜索了几篇文章,也没注意什么时候的,发现都讲的不彻底,综合一下,也当个学习笔记. using S ...

  3. C#事件(event)解析

    事件(event),这个词儿对于初学者来说,往往总是显得有些神秘,不易弄懂.而这些东西却往往又是编程中常用且非常重要的东西.大家都知道windows消息处理机制的重要,其实C#事件就是基于window ...

  4. C#中的委托(Delegate)和事件(Event)

    原文地址:C#中的委托(Delegate)和事件(Event) 作者:jiyuan51 把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写的设计模式--观察者(Obs ...

  5. 重温委托(delegate)和事件(event)

    1.delegate是什么 某种意义上来讲,你可以把delegate理解成C语言中的函数指针,它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m,说白了就是可以把方法当作 ...

  6. Yii2基本概念之——事件(Event)

    说起事件(event),我们可是一点都不陌生.现实生活当中的事件无处不在,比如你发了一条微博,触发了一条事件,导致关注你的人收到了一条消息,看到你发的内容:比如你通过支付宝买东西,付了款,触发一个事件 ...

  7. {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器

    Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...

  8. 详解 Solidity 事件Event - 完全搞懂事件的使用

    很多同学对Solidity 中的Event有疑问,这篇文章就来详细的看看Solidity 中Event到底有什么用? 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊. ...

  9. Spark2.1.0——深入理解事件总线

    Spark2.1.0——深入理解事件总线 概览 Spark程序在运行的过程中,Driver端的很多功能都依赖于事件的传递和处理,而事件总线在这中间发挥着至关重要的纽带作用.事件总线通过异步线程,提高了 ...

随机推荐

  1. IE10下 FormsAuthentication.SetAuthCookie无效的问

    问题是这样的,我在本地测试设置身份验证票据都没问题,发布到服务器后访问地址添加了一些特殊的字符,看起来像加过密的,如下: http://www.example.com/(F(1xe9eXIxPzMAL ...

  2. spring boot获取前端参数四种方法

    一:直接参数绑定 @RequestMapping("/hello") @ResponseBody public String hello(String para) { // par ...

  3. 微服务深入浅出(5)-- 声明式调用Feign

    Feign的使用 Feign采用了声明式的API接口的风格,将Java Http客户端绑定到它的内部,从而调用过程变的简单. 配置文件: spring: application: name: eure ...

  4. sql_injection之基本get注入

    1.代码篇 <?php error_reporting(0); include("../conn.php"); if(isset($_GET['id'])){ $id=$_G ...

  5. Dream------Hadoop--Hadoop HA QJM (Quorum Journal Manager)

    In a typical HA cluster, two separate machines are configured as NameNodes. At any point in time, ex ...

  6. Redis简介——(一)

    1.关于关系型数据库和nosql数据库 关系型数据库是基于关系表的数据库,最终会将数据持久化到磁盘上,而nosql数据 库是基于特殊的结构,并将数据存储到内存的数据库.从性能上而言,nosql数据库 ...

  7. webpack4.5.0+vue2.5.16+vue-loader 实战组件化开发案例以及版本问题中踩的一些大坑!!!

    一 vue-loader 我们先不管脚手架,只说vue-loader,简单讲就是可将.vue文件打包,实现组件化开发,即一个.vue文件就是一个组件,开发中只需要引入这个.vue组件就可以了! 然后. ...

  8. Python Webdriver 重新使用已经打开的浏览器实例

    因为Webdriver每次实例化都会新开一个全新的浏览器会话,在有些情况下需要复用之前打开未关闭的会话.比如爬虫,希望结束脚本时,让浏览器处于空闲状态.当脚本重新运行时,它将继续使用这个会话工作.还就 ...

  9. 你需要知道的12个Git高级命令【转】

    转自:http://www.linuxidc.com/Linux/2016-01/128024.htm 众所周知,Git目前已经是分布式版本控制领域的翘楚,围绕着Git形成了完整的生态圈.学习Git, ...

  10. Python 使用 Redis 操作

    1.redis简介 redis是一款开源免费的高性能key-value数据库,redis特点: 支持更多的数据类型:字符串(String).列表(List).哈希(Map).数字(Int).集合(Se ...