在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式、委托与事件的方式实现过观察者模式。本篇体验使用Action实现此模式,并从中体验委托与事件的区别。

□ 使用Action实现观察者模式

就举一个足球场上的例子,当裁判吹响终场哨,胜队庆祝,失败队落寞。把裁判看作是被观察者,比赛中的两队看作是观察者。

裁判作为被观察者需要提供一个Action委托供观察者方法注册。

    public class Referee
    {
        public Action DoSth;
        public void ISayGameOver()
        {
            Console.WriteLine("嘀嘀嘀......比赛结束了~~");
            DoSth();
        }
    }

胜利的队和失败的队拥有共同的基类。

    public class Team
    {
        private string _name;
        public Team(string name)
        {
            _name = name;
        }
        public string Name
        {
            get { return _name; }
        }
    }

胜利队或失败队,作为观察者,必须有符合Referee中Action定义的方法。

    public class WinTeam : Team
    {
        public WinTeam(string name) : base(name){}
        public void Celebrate()
        {
            Console.WriteLine("我们晋级了,好开心!");
        }
    }
    public class LoseTeam : Team
    {
        public LoseTeam(string name) : base(name){}
        public void WeAreSad()
        {
            Console.WriteLine("比赛输了,好伤心!");
        }
    }

客户端,先把失败队和胜利队的方法注册到Action变量,然后由被观察者的一个方法触发委托链和方法。

        static void Main(string[] args)
        {
            Referee referee = new Referee();
            var winTeam = new WinTeam("胜利队");
            var loseTeam = new LoseTeam("失败队");
            //注册观察者
            referee.DoSth += winTeam.Celebrate;
            referee.DoSth += loseTeam.WeAreSad;
            //被观察者启动事件通知观察者
            referee.ISayGameOver();
        }

□ 体验委托与事件的区别

现在,我们在客户端,在调用Referee的实例方法ISayGameOver之前,尝试把Referee的委托变量DoSth设置为null。

        static void Main(string[] args)
        {
            Referee referee = new Referee();
            var winTeam = new WinTeam("胜利队");
            var loseTeam = new LoseTeam("失败队");
            //注册观察者
            referee.DoSth += winTeam.Celebrate;
            referee.DoSth += loseTeam.WeAreSad;
            referee.DoSth = null;
            //被观察者启动事件通知观察者
            referee.ISayGameOver();
        }


可见,当把把Referee的委托变量DoSth设置为null后,所有注册的方法将得不到执行。

如果把Referee的委托变量DoSth修饰为事件。

    public class Referee
    {
        public event Action DoSth;
        public void ISayGameOver()
        {
            Console.WriteLine("嘀嘀嘀......比赛结束了~~");
            if (DoSth != null)
            {
                DoSth();
            }

        }
    }


可见,当把委托变量DoSth修饰为事件后,只能通过+=和-=注册、取消方法,不能通过=设置。

把referee.DoSth = null;注释掉,将不会报错。

“委托、Lambda表达式、事件系列”包括:

委托、Lambda表达式、事件系列01,委托是什么,委托的基本用法,委托的Method和Target属性

委托、Lambda表达式、事件系列02,什么时候该用委托

委托、Lambda表达式、事件系列03,从委托到Lamda表达式

委托、Lambda表达式、事件系列04,委托链是怎样形成的, 多播委托, 调用委托链方法,委托链异常处理

委托、Lambda表达式、事件系列05,Action委托与闭包

委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别

委托、Lambda表达式、事件系列07,使用EventHandler委托

委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别...相关推荐

  1. 【C# 委托 Lambda表达式】一个简单的例子

    委托 委托类似于C++函数指针,但委托是完全是面向对象的,是安全的数据类型. 委托允许将方法作为参数进行传递. 运行结果 j=25 代码 using System; using System.Coll ...

  2. 委托、Lambda表达式、事件系列07,使用EventHandler委托

    谈到事件注册,EventHandler是最常用的. EventHandler是一个委托,接收2个形参.sender是指事件的发起者,e代表事件参数. □ 使用EventHandler实现猜拳游戏 使用 ...

  3. C#——Lambda表达式与泛型委托DEMO

    问题描述 按要求编写Lambda表达式: .NET已定义的Func<out TResult>是一个泛型委托,它封装一个方法,该方法不具有参数,且返回由 TResult 参数指定的类型的值. ...

  4. [C# 基础知识系列]专题十四:深入理解Lambda表达式

    引言: 对于刚刚接触Lambda表达式的朋友们,可能会对Lambda表达式感到非常疑惑,它到底是个什么什么样的技术呢?以及它有什么好处和先进的地方呢?下面的介绍将会解除你这些疑惑. 一.Lambda表 ...

  5. C# 委托,匿名方法,lambda表达式使用方法

    在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法. C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式. ...

  6. delegate、Lambda表达式、Func委托和Expression(TDelegate)表达式目录树

    1.delegate MSDN:一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似.与 C 中的函数指针不同,委托是面向对象的.类型安全的和保险的.委托的类型由委托的名称定义 class ...

  7. C#中的委托,匿名方法和Lambda表达式

    简介在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=5.答案是6个Firs ...

  8. C#复习笔记(4)--C#3:革新写代码的方式(Lambda表达式和表达式树)

    Lambda表达式和表达式树 先放一张委托转换的进化图 看一看到lambda简化了委托的使用. lambda可以隐式的转换成委托或者表达式树.转换成委托的话如下面的代码: Func<string ...

  9. 匿名内部类以及Lambda表达式(Java和C#)

    就来说一说这个匿名内部类,用Java做例子,后面插一点c#.这个东西我之前也知道了很久,一直没有认真去看过,这次就来看看吧,今天的代码量相对很多. 匿名内部类 这里就说匿名内部类,关于其他内部类老规矩 ...

最新文章

  1. (14)Why some people find exercise harder than others
  2. java的调试工具_2020年最佳Java调试工具(翻译)
  3. 为什么说Java中只有值传递(另一种角度)
  4. 收藏的一些github开源项目,在这里记录一下
  5. 怎么单选_听力三个选项都出的单选怎么破?| 附今日听力S1S2及听力原文
  6. “蓝桥杯”练习系统练习题答案(自己做的)
  7. 由电子领域延伸的技术视野
  8. 虚拟地址空间和物理地址空间
  9. 世界芯中国芯RISC-V相关资源及进展
  10. 数据分析——AB测试
  11. 这样一张手绘说明书,我竟然调试通了,SYN8086TTS模块现场评测教学
  12. 因为计算机中丢失MSVCp,无法启动此程序,因为计算机中丢失MSVCP140.dll的
  13. 大学计算机课程进制的转换教程,交大计算机课程(1):各种进制转换
  14. 微信小程序开发工具的目录结构
  15. spring boot启动报错: The APR based Apache Tomcat Native library which allows optimal performance
  16. 大象跳转:解析微信内自动跳转浏览器打开URL网页的操作步骤
  17. 洛谷 P3620 - P3621 数据备份、风铃、动物园(APIO 2007)
  18. CF1139D Steps to One 题解
  19. 大数据-HADOOP高可用、联邦机制- 学习笔记 -BH4
  20. LaTeX 表格和图片在文中引用时编号显示问题

热门文章

  1. 数组的顺序存储和实现
  2. 基于 Apache Mahout 构建社会化推荐引擎
  3. RPC 框架之 Goole protobuf
  4. 突然情怀就上来啦,‘闭包’ 今天咱们讲一下子
  5. 开发常用技巧之css字体编码
  6. 智能SQL优化工具--SQL Optimizer for SQL Server(帮助提升数据库应用程序性能,最大程度地自动优化你的SQL语句 )...
  7. 获取当前程序的相当路径
  8. 面向对象编程Sample(C#)
  9. 让你彻底明白什么叫游戏引擎(2)
  10. pytorch---之cudnn.benchmark和cudnn.deterministic