前面一篇里提到事件是通过委托来进行关联的,而委托是可以带各种各样的参数的,其中就可以用事件参数(EventArgs),同时,也可以用.Net框架里边提供的一个委托EventHandler来Handle事件。

一样,搞一个场景(这个场景是书里的):买车。经销商(CarDealer)会上新车(NewCar)事件,这个事件会由买车的顾客(Comsumer)订阅,一旦有新车出来他们就会来光顾。在这里,由于需要详细的车的信息,所以使用前面提到的不带参数的方法就比较麻烦,我们重新定义一个委托(delegate)和事件参数(EventArgs)。

1、事件参数(CarInfoEventArgs)

从.Net提供的EventArgs里派生出来,包含车辆名字的属性

public class CarInfoEventArgs : EventArgs
{
    public string Car { get; private set; }

    public CarInfoEventArgs(string car)
    {
        this.Car = car;
    }
}

2、事件(NewCarInfo)

这里使用.Net自带的委托EventHandler来声明一个事件,相应的,这个事件的处理程序就必须使用这个委托对应的参数来构建

public event EventHandler<CarInfoEventArgs> NewCarInfo;

注意,这是一个泛型委托,在这里指定了参数的类型为CarInfoEventArgs,EventHandler的定义如下:

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e)
    where TEventArgs : EventArgs

可以看到这个委托包含两个参数:一个object类型,一个泛型参数,并且这个泛型参数被限制为EventArgs或EventArgs派生的类型

3、完整的对象

CarDealer

public class CarDealer
{
    public event EventHandler<CarInfoEventArgs> NewCarInfo;

    // 触发事件
    public void NewCar(string car)
    {
        Console.WriteLine($"CarDealer, new car {car}");
        if (NewCarInfo != null)
        {
            NewCarInfo(this, new CarInfoEventArgs(car));
        }
    }
}

Consumer

public class Consumer
{
    public string Name { get; private set; }

    public Consumer(string name)
    {
        this.Name = name;
    }

    public void NewCarIsHere(object sender, CarInfoEventArgs e)
    {
        Console.WriteLine($"{name}: car {e.Car} is new");
     }
}

4、具体的实现

public class Program
{
    static void Main()
    {
        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");
    }
}

执行结果如下:

C# 委托和事件(二):使用.Net框架中的EventArgs和EventHandler的更多相关文章

  1. C#编程之委托与事件四(二)【转】

    C#编程之委托与事件(二)       我在上一篇文章(C#编程之委托与事件(一) )中通过示例结合的方法介绍了委托,在本文中,我同样以代码示例的方式来介绍C#里的事件机制. 二.事件   1.了解概 ...

  2. c#委托、事件、Observer

    委托和事件在.NET Framework[1] 中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易. 中文名 委托 外文名 Delegate 编程语言 C# 作     ...

  3. 牛客网Java刷题知识点之Java 集合框架的构成、集合框架中的迭代器Iterator、集合框架中的集合接口Collection(List和Set)、集合框架中的Map集合

    不多说,直接上干货! 集合框架中包含了大量集合接口.这些接口的实现类和操作它们的算法. 集合容器因为内部的数据结构不同,有多种具体容器. 不断的向上抽取,就形成了集合框架. Map是一次添加一对元素. ...

  4. Unity C# 多态 委托 事件 匿名委托 Lambda表达式 观察者模式 .NET 框架中的委托和事件

    一.多态 里氏替换原则: 任何能用基类的地方,可以用子类代替,反过来不行.子类能够在基类的基础上增加新的行为.面向对象设计的基本原则之一. 开放封闭原则: 对扩展开放,意味着有新的需求或变化时,可以对 ...

  5. 解密jQuery事件核心 - 委托设计(二)

    第一篇 http://www.cnblogs.com/aaronjs/p/3444874.html 从上章就能得出几个信息: 事件信息都存储在数据缓存中 对于没有特殊事件特有监听方法和普通事件都用ad ...

  6. 委托、事件、Observer观察者模式的使用解析二

    一.设计模式-Observer观察者模式 Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新.Observer模式是一种 ...

  7. C#编程语言之委托与事件(二)—— C#事件

    前面已经大致讲述了C#委托的一些基础知识点,本文接下来的内容是C#中的事件(Event),在此我提个建议,如果是刚接触C#的委托类型的朋友可以先看到这里,等熟悉了委托的使用之后(大约1-2天)再来了解 ...

  8. C#编程(四十二)----------委托和事件

    委托和事件 委托是C#总比较重要的概念,学习C#爱这里最容易产生迷惑. 有些时候,犹豫我们在开发程序时对后续可能出现的要求及变化考虑不足而导致麻烦,这些新变化可能导致程序的重新编写,那能不能改变这种情 ...

  9. 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码

    详解C#泛型(二)   一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...

随机推荐

  1. WPF版的权限管理系统

    好多技术人员都有一个通病,不关注用户的需求,产品的可用性,只看使用的技术的新不新,潮不潮,这就是所谓的技术发烧友. 这段时间,断断续续的开发一个WPF的软件,也拿出来Show一下.要不放在硬盘里就发霉 ...

  2. 小议map排序问题

    map有序无序?如果说有序, 这个顺序是怎么定义的? 安装put的先后顺序吗? 还是被put元素的内容呢? 经观察,应该是后者,跟put先后顺序无关, 跟内部实现有关(可能是hash排序的, 非大小排 ...

  3. 基础才是重中之重~ConcurrentDictionary让你的多线程代码更优美

    回到目录 ConcurrentDictionary是.net4.0推出的一套线程安全集合里的其中一个,和它一起被发行的还有ConcurrentStack,ConcurrentQueue等类型,它们的单 ...

  4. 爱上MVC~为DisplayNameFor添加扩展,支持PagedList集合

    回到目录 DisplayNameFor方法是MVC提供给我们的,它可以将模型的DisplayName特性的值显示到页面上,这对程序员来说很是方便,在进行实体设计时,可以指定它的显示名称,然后MVC引擎 ...

  5. token防止表单重复提交

    出现表单重复提交的三种情况: 一.服务器响应缓慢,用户多次点击提交按钮. 二.提交成功后刷新页面. 三.提交成功后返回表单页面再次点击提交. package com.jalja.token; impo ...

  6. KnockoutJS 3.X API 第五章 高级应用(5) 使用预处理扩展Knockout绑定语法

    注意:这是一种高级技术,通常仅在创建可重用绑定或扩展语法的库时使用. 这不是你通常需要做的时候使用Knockout构建应用程序. 从Knockout 3.0开始,开发人员可以通过提供在绑定过程中重写D ...

  7. Android Studio下载及使用教程(转载)

    (一)下载及相关问题解决: Android Studio 下载地址,目前最新可下载地址,尽量使用下载工具. Android Studio正式发布,给Android开发者带来了不小的惊喜.但是下载地址却 ...

  8. 快速入门系列--WCF--08扩展与新特性

    最后一章将进行WCF扩展和新特性的学习,这部分内容有一定深度,有一个基本的了解即可,当需要自定义一个完整的SOA框架时,可以再进行细致的学习和实践. 服务端架构体系的构建主要包含接下来的几个要素:服务 ...

  9. SQL Server 2012 T-SQL 新特性

    序列 Sequence SQL Server 现在将序列当成一个对象来实现,创建一个序列的例子语法如下: CREATE SEQUENCE DemoSequence START WITH 1 INCRE ...

  10. java中得到classpath和当前类的绝对路径的一些方法(路径中的%20"进行替换空格)

    原网址:http://blog.csdn.net/shendl/article/details/1427475 (注意:利用下面方式得到路径,如果路径中有空格字符, 那么会有"%20&quo ...