C#的事件基于委托,所以先说委托。

一切脱离实际场景的抽象概念新手看上去就像是在扯犊子,不错,我就是个新手。所以我需要一个实际的场景。

明天刚好考试(商务英语),考试上有两个角色(class):老师(Teacher)和学生(Student),在考试时间终止的时候,老师会触发(invoke)一个事件(event):“考试时间到了,我tm要收卷子了!”(OnTestTimeUp),而每个学生都要订阅这个事件,并在这个事件发生的时候上交试卷(HandInTestPaper)。如果不用事件的话,老师在时间结束的时候就要调用每个学生的的HandInTestPaper方法,如果使用事件,只要在学生被实例化的时候在事件上增加一个订阅即可。

1、老师和学生之间的桥梁

老师和学生之间的桥梁用委托来完成,这里就用最简单的一种委托:没有返回、没有参数、不支持泛型:

public delegate void TestTimeUpHandler();

接着,用这个委托定义一个事件,这样学生就可以订阅这个事件

public event TestTimeUpHandler TestTimeUp;

学生订阅事件后,当老师触发这个事件的时候,学生就会做出一些响应

public void OnTestTimeUp()
{
    TestTimeUp?.Invoke();
}

2、学生如何订阅?

首先回到刚才的委托,这个委托非常简单,没有返回、没有参数,所以学生类中只要有一个方法,签名与这个一致就可以订阅这个事件:

public void HandInTestPaper()
{
    Console.WriteLine("The test paper has been handed in.");
}

然后在实例化后直接将这个方法订阅给事件即可

3、两边的关系

4、完整的例子

Delegate

    /// <summary>
    /// 委托,考试时间到的Handler
    /// </summary>
    public delegate void TestTimeUpHander();

Teacher

    /// <summary>
    /// 教师类
    /// </summary>
    public class Teacher
    {
        public event TestTimeUpHander TestTimeUp;

        public void OnTestTimeUp()
        {
            TestTimeUp?.Invoke();
        }
    }

Student

    /// <summary>
    /// 学生类
    /// </summary>
    public class Student
    {
        public string Name { get; private set; }

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

        public void HandInTestPaper()
        {
            Console.WriteLine($"{this.Name}\' paper has been handed in");
        }
    }

5、具体场景实现

    public class Program
    {
        public static void Main()
        {
            Teacher teacher = new Teacher();
            var tom = new Student("Tom");
            var jerry = new Student("Jerry");
            var spark = new Student("Spark");
            var tyke = new Student("Tyke");

            // 订阅teacher的TestTimeUp事件
            teacher.TestTimeUp += tom.HandInTestPaper;
            teacher.TestTimeUp += jerry.HandInTestPaper;

            // invoke TestTimeUp 事件
            teacher.OnTestTimeUp();

            Console.WriteLine();

            teacher.TestTimeUp -= tom.HandInTestPaper;
            teacher.TestTimeUp += tyke.HandInTestPaper;

       teacher.OnTestTimeUp(); Console.ReadKey(); } }

运行的结果如下:

可以看到,第一次触发事件的时候,只有Tom和Jerry两个订阅了事件的实例执行了HandInTestPaper方法,第二次触发事件前,移除了Tom的订阅,同时增加了Tyke的订阅,所以Jerry和Tyke执行了HandInTestPaper方法。

以上,是最简单的C#委托与事件的实现,复杂的方法日后再说

C# 委托和事件(一):最简单的委托和事件的更多相关文章

  1. 【转】C# 中的委托和事件

    阅读目录 C# 中的委托和事件 引言 将方法作为方法的参数 将方法绑定到委托 事件的由来 事件和委托的编译代码 委托.事件与Observer设计模式 .Net Framework中的委托与事件 总结 ...

  2. 《C#高级编程》学习笔记------C#中的委托和事件(续)

    本文转载自张子阳 目录 为什么要使用事件而不是委托变量? 为什么委托定义的返回值通常都为void? 如何让事件只允许一个客户订阅?(事件访问器) 获得多个返回值与异常处理 委托中订阅者方法超时的处理 ...

  3. C#中的委托和事件(续)

    转自张子阳的博客http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-Advanced.aspx 引言 如果你看过了 C#中 ...

  4. .NET之美——C#中的委托和事件(续)

    C#中的委托和事件(续) 引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为 ...

  5. C#中的委托和事件2-2(转)

    引言 如果你看过了 C#中的委托和事件2-1 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为细节的问题,包括一些 ...

  6. 转:C#中的委托和事件(续)

    引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为细节的问题,包括一些大家常 ...

  7. C#中的委托和事件(二)

    引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为细节的问题,包括一些大家常 ...

  8. [转]C#中的委托和事件(续)

    源码下载:http://www.tracefact.net/SourceCode/MoreDelegate.rar C#中的委托和事件(续) 引言 如果你看过了 C#中的委托和事件 一文,我想你对委托 ...

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

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

随机推荐

  1. 在.net中使用aquiles访问Cassandra(一)

    aquiles是.net下基于Thrift协议访问Cassandra的第三方类库,官方地址是: http://aquiles.codeplex.com/   1.下载类库文件: http://aqui ...

  2. 微软专家推荐11个Chrome 插件

    Web开发人员,需要长时间使用浏览器,尽管Windows10 Edge浏览器启动非常快速,且支持110多种设备,Edge支持基于JS 扩展,但也删除了很多旧功能像Active-X等插件.多数情况下,插 ...

  3. 一则线上MySql连接异常的排查过程

    Mysql作为一个常用数据库,在互联网系统应用很多.有些故障是其自身的bug,有些则不是,这里以前段时间遇到的问题举例. 问题 当时遇到的症状是这样的,我们的应用在线上测试环境,JMeter测试过程中 ...

  4. java source not found

    今天的挑战是,为什么与源码明明放在本机,调试的时候却说source not found呢? 这个是因为,我重新建立了debug,然后没有选择对应的项目. 另外一个问题是,如果给底层的jar附上源码呢?

  5. CentOS 6.6下Redis安装配置记录

    转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/120.html?1455855209 在先前的文章中介绍过redis,以下 ...

  6. Atitit 发帖机实现(4 )- usbQBM1601 gui操作标准化规范与解决方案attilax总结

    Atitit 发帖机实现(4 )- usbQBM1601 gui操作标准化规范与解决方案attilax总结 1.1. 根据gui的类型使用不同的gui调用api1 1.2. Script化1 1.3. ...

  7. Ajax技术

    1.ajax技术的背景 不可否认,ajax技术的流行得益于google的大力推广,正是由于google earth.google suggest以及gmail等对ajax技术的广泛应用,催生了ajax ...

  8. iOS-网络爬虫

    1.iOS开发——网络实用技术OC篇&网络爬虫-使用青花瓷抓取网络数据 2.iOS开发——网络使用技术OC篇&网络爬虫-使用正则表达式抓取网络数据 3.iOS—网络实用技术OC篇&am ...

  9. 利用SSIS的ForcedExecutionResult 属性 和CheckPoint调试Package

    1,ForcedExecutionResult 强制一个package或task执行的结果,共有四种值 None,Success,Failure,Completion,默认值是None,表示不强制返回 ...

  10. PHP 字符串函数

    字符串是字符序列,比如 "Hello world!". PHP 字符串函数 在本节中,我们将学习常用的字符串操作函数. PHP strlen() 函数 strlen() 函数返回字 ...