讲过了委托,不得不讲事件。

事件基于委托,为委托提供了一种发布/订阅机制。

在发生其他类或对象关注的事情时,类或对象可通过事件通知它们。发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为“订户”。

在典型的 C# Windows 窗体或 Web 应用程序中,可订阅由控件(如按钮和列表框)引发的事件。可使用 Visual C# 集成开发环境 (IDE) 来浏览控件发布的事件,选择要处理的事件。IDE 会自动添加空事件处理程序方法和订阅事件的代码。

事件时对委托的封装。

事件帮助解决委托封装问题。事件位于委托的顶部,并提供封装,使得目标源只能听而不能完全控制的委托对象。

下图显示了事件的样子: -

理解事件:

Button是一个类,当你点击按钮的时候,Click事件被触发。

定时器是一个类,每毫秒tick事件被触发。

下面通过一个例子来讲述一下事件的应用。

定义两个类CarDealer和Consumer。CarDealer类提供了一个新车到达时触发的事件,Consumer类订阅该事件,以获得新车到达的通知。

事件发布程序:CarDealer类提供了EventHandler类型的NewCarInfo事件。事件一般使用带两个参数的方法。第一个参数是一个对象,包含事件的发送者;第二个参数提供了事件的相关信息。

你可能感到吃惊,没有定义委托怎么就定义事件了??其实有了泛型委托EventHandler 委托后,就不再需要委托了。

EventHandler 的语法如下:

public delegate void EventHandler(Object sender,TEventArgs e) where TEventArgs : EventArgs

EventHandler定义了一个处理程序,返回void,接受两个参数。第一个参数必须是object,第二个参数是T类型,对于T有一个约束,就是它必须派生自基类EventArgs。下面代码的CarInfoEventArgs就派生自基类EventArgs.

EventArgs是包含事件数据的类的基类,此类不包含事件数据,在事件引发时不向事件处理程序传递状态信息的事件会使用此类。如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。事件处理程序委托的标准签名定义一个没有返回值的方法,其第一个参数的类型为 Object,它引用引发事件的实例,第二个参数从 EventArgs 类型派生,它保存事件数据。 如果事件不生成事件数据,则第二个参数只是 EventArgs 的一个实例。 否则,第二个参数为从 EventArgs 派生的自定义类型,提供保存事件数据所需的全部字段或属性。

EventHandler 是一种预定义委托,表示事件的事件处理程序方法,它与事件是否生成事件数据无关。 如果事件不生成事件数据,则用 EventArgs 替代泛型类型参数;否则,提供自己的自定义事件数据类型并用该类型替代泛型类型参数。

使用 EventHandler 的优点在于,如果事件生成事件数据,则无需编写自己的自定义委托代码。 此外,.NET Framework 只需一个实现就能支持 EventHandler ,这与替代泛型类型参数的事件数据类型无关。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestEvent
{
public class CarInfoEventArgs:EventArgs
{
public CarInfoEventArgs(string car)
{
this.Car = car;
}
public string Car{get; private set;}
}
public class CarDealer
{
public event EventHandlerNewCarInfo;
public void NewCar(string car)
{
Console.WriteLine("CarDealer. new car {0}", car);
if (NewCarInfo != null)
{
NewCarInfo(this, new CarInfoEventArgs(car));
}
}
}
}

事件监听器:Consumer类用作事件侦听器。这个类订阅了CarDealer类的事件,并定义了NewCarIsHere方法,该方法满足EventHandler委托的要求,其参数类型是object和CarInfoEventArgs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestEvent
{
class Consumer
{
private string name;
public Consumer(string name)
{
this.name = name;
}
public void NewCarIsHere(object sender, CarInfoEventArgs e)
{
Console.WriteLine("{0}: car {1} is new", name, e.Car);
}
}
}

现在需要连接事件发布器和订阅器。使用“+=”创建一个订阅。使用“-=”取消了订阅。使用代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestEvent
{
class Program
{
static void Main(string[] args)
{
var dealer = new CarDealer();
var michael = new Consumer("Michael");
dealer.NewCarInfo += michael.NewCarIsHere;
dealer.NewCar("Mercedes");
var nick = new Consumer("Nick");
dealer.NewCarInfo += nick.NewCarIsHere;
dealer.NewCar("Ferrari");
dealer.NewCarInfo -= michael.NewCarIsHere;
dealer.NewCar("Toyota");
}
}
}
/*-------------------------------------
输出结果:
CarDealer. new car Mercedes
Michael: car Mercedes is new
CarDealer. new car Ferrari
Michael: car Ferrari is new
Nick: car Ferrari is new
CarDealer. new car Toyota
Nick: car Toyota is new
---------------------------------------*/
https://www.cnblogs.com/sjqq/p/6918006.html

浅析C#中的事件的更多相关文章

  1. 浅析 JavaScript 中的 函数 currying 柯里化

    原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...

  2. 浅析 Linux 中的时间编程和实现原理一—— Linux 应用层的时间编程【转】

    本文转载自:http://www.cnblogs.com/qingchen1984/p/7007631.html 本篇文章主要介绍了"浅析 Linux 中的时间编程和实现原理一—— Linu ...

  3. 深入浅析python中的多进程、多线程、协程

    深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...

  4. C++中的事件分发

    本文意在展现一个C++实现的通用事件分发系统,能够灵活的处理各种事件.对于事件处理函数的注册,希望既能注册到普通函数,注册到事件处理类,也能注册到任意类的成员函数.这样在游戏客户端的逻辑处理中,可以非 ...

  5. javascript中的事件冒泡和事件捕获

    1.事件冒泡 IE 的事件流叫做事件冒泡(event bubbling),即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档).以下面的HTML ...

  6. jQuery文本框中的事件应用

    jQuery文本框中的事件应用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "ht ...

  7. 怎么理解js中的事件委托

    怎么理解js中的事件委托 时间 2015-01-15 00:59:59  SegmentFault 原文  http://segmentfault.com/blog/sunchengli/119000 ...

  8. jQuery中的事件绑定方法

    在jQuery中,事件绑定方法大致有四种:bind(),live(), delegate(),和on(). 那么在工作中应该如何选择呢?首先要了解四种方法的区别和各自的特点. 在了解这些之前,首先要知 ...

  9. 四、jquery中的事件与应用

    当用户浏览页面时,浏览器会对页面代码进行解释或编译--这个过程实质上是通过时间来驱动的,即页面在加载时,执行一个Load事件,在这个事件中实现浏览器编译页面代码的过程.时间无论在页面元素本身还是在元素 ...

随机推荐

  1. 本地连接出现"已启用检测该状态的服务"解决方法、方案

    1.运行 输出dcomcnfg 2.组件服务-计算机-我的电脑-DCOM配置-netprofm 3.右键属性-安全-启动和激活权限-自定义 4.编辑-添加-输入对象名称来选择-输入“LOCAL SER ...

  2. ML三(人工神经网络)

    人工神经网络 Artificial Neural Nerworks 基本术语概念: 人工神经网络(Artificial Neural Networks,ANN) 感知器(Perceptron):以一个 ...

  3. Python的进度条的制作

    import sys,time #导入模块 for i in range(50): #进度条的长度 sys.stdout.write("#") #进度条的内容,这里要注意了,pyc ...

  4. python MLP 神经网络使用 MinMaxScaler 没有 StandardScaler效果好

    MLP 64,2  preprocessing.MinMaxScaler().fit(X)                               test confusion_matrix:[[ ...

  5. SWFObject是什么

    一:简介: SWFObject是一个用于在HTML中方便插入Adobe Flash媒体资源(*.swf文件)的独立.敏捷的JavaScript模块.该模块中的JavaScript脚本能够自动检测PC. ...

  6. poj-1442 Black Box(Treap)

    题目链接: Black Box 题意: 给一个序列,m个询问,每个询问是求前x个数中的第i小是多少; 思路: Treap的入门题目;Treap能实现STL的set实现不了的功能,如名次树(rank t ...

  7. PS 滤镜— —Marble 效果

    clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Processing\PS Algorithm'); I=imread ...

  8. 【leetcode刷题笔记】Best Time to Buy and Sell Stock III

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  9. NOIP2018爆炸记

    又是一年\(NOIP\),可能是梦结束的地方? 之所以咕了这么久是得先确定自己不会退役,因为分太低了. 和去年一样在学校门前照了相,然后上车走了.高三回来考的只剩下\(p2oileen\)学姐了.新一 ...

  10. 使用Visual Studio进行单元测试-Shim类中无法找到参数包含CancellationTokenSource的方法

    Shim类中无法找到参数包含CancellationTokenSource的方法,这句话有点绕口,看例子. 一.代码 public class CancellationDemo { public in ...