专栏首页.Net、.Net Core 、Docker委托与事件-委托事件案例(三)

委托与事件-委托事件案例(三)

前言

  这两天一直在想如何结合实际案例来结束委托与事件的讲解,下面讲解两个事例,用来加深对委托及事件的理解。

事例一(分页功能)

  本场景是用来讲解使用的,具体内容功能需自行填补实现。用委托加事件来实现分页功能的通用。按上一节讲解中的逻辑处理,分为订阅者和发布者,一样的可以先定义订阅者感兴趣的对象,然后发布者,订阅者。再就是主程序调用。

     /// <summary>
    /// 首先定义订阅者感兴趣的对象,本例感兴趣的是上一页下一页等方法。这里使用Action抽象
    /// </summary>
    public class PageChangeEventArgs : EventArgs
    {
        public string Action { get; set; }
        public int PageIndex { get; set; }
        public PageChangeEventArgs() { }
        public PageChangeEventArgs(string action, int pageIndex)
        {
            this.Action = action;
            this.PageIndex = pageIndex;
        }
    }

    /// <summary>
    /// 定义发布者
    /// </summary>
    public class PageActionPubliser
    {
        //定义委托
        public delegate void PageActionEventHandler(object sender, PageChangeEventArgs e);
        //定义委托类型的事件
        public event PageActionEventHandler PageAction;
        //定义保护方法判断委托事件是否为空,传入参数e类型为EventArgs
        protected void OnPageAction(PageChangeEventArgs e)
        {
            if (PageAction != null)
            {
                PageAction(this, e);
            }
            //PageAction?.Invoke(this, e);也可这样写
        }

        //编写触发事件、上一页
        public void PreviousClick( PageChangeEventArgs e)

        {
            OnPageAction(new PageChangeEventArgs("Previous",e.PageIndex));
        }
        //下一页
        public void NextClick( PageChangeEventArgs e)
        {
            OnPageAction(new PageChangeEventArgs("Next",e.PageIndex));
        }
 
    }

 
    /// <summary>
    /// 定义订阅者
    /// </summary>
    public class Recevice
    {
        /// <summary>
        /// 具体分页内容的实现,订阅者
        /// </summary>
        public static void BindPage(object sender, PageChangeEventArgs e)
        {

            //假设最大页数为10
            int MaxIndex = 10;

            if (e.PageIndex == 0 && e.Action == "Previous")
            {
                //当前0页,不能上一页
            }

            if (e.PageIndex == MaxIndex - 1 && e.Action == "Next")
            {
                //已是最后一页,不能下一页
            }
            switch (e.Action)
            {
                case "Previous":
                    e.PageIndex--;
                    break;
 
                default:
                    e.PageIndex++;
                    break;
            }
            Console.WriteLine($"已跳转到第{e.PageIndex}页");
        }
        
    }

         /// <summary>
        /// 这里使用的是控制台应用程序进行模拟
        /// </summary>
        /// <param name="args"></param>
    class Program
    {
       
        static void Main(string[] args)
        {
            //绑定注册事件
            PageActionPubliser pageActionPubliser = new PageActionPubliser();
            pageActionPubliser.PageAction += Recevice.BindPage;
            Console.WriteLine("请选择上一页或者下一页:上一页(A)/下一页(B)");
            string answer=Console.ReadLine();
            PageChangeEventArgs pageChangeEventArgs = new PageChangeEventArgs();

            //假设当前页为5
            pageChangeEventArgs.PageIndex = 5;
            if (answer=="A")
            {                        
            pageActionPubliser.PreviousClick(pageChangeEventArgs);
            }

            else
            {
                pageActionPubliser.NextClick(pageChangeEventArgs);
            }

        }

    }    

  在这里委托加事件的分页功能实现完成了。其实原理很简单的,当点击上一页或者下一页的时候,这时候因为因为已经绑定注册了这个事件。 它就会具体执行其中的操作。还是要具体去实践编写操作调试一下,就很快知道它的执行顺序、也能很快的掌握的。

事例二(新车到达提醒)

  这个案例,简要的表述就是在车库中新到达了车辆时会对管理者发送通知。首先我们也先分析下。订阅者是管理者。订阅者感兴趣的对象是啥呢?感兴趣的对象是有没有新车达到。

  然后,我们开始这个的一个设计。

    /// <summary>
    /// 定义订阅者感兴趣的对象
    /// </summary>
    public class NewCarsEventArgs : EventArgs
    {
        public string NewCardName { get; set; }
        public NewCarsEventArgs() { }
        public NewCarsEventArgs(string newCardName)
        {
            this.NewCardName = newCardName;
        }
    }


    /// <summary>
    /// 定义发布者
    /// </summary>
    public class NewCarsPublisher
    {
        public delegate void CarsEventHandler(object sender ,NewCarsEventArgs e);
        public event CarsEventHandler Cars;
        private void OnCars(NewCarsEventArgs e)
        {
            if (Cars!=null)
            {
                Cars(this,e);
            }
        }
        public void NewCarsArrivals(NewCarsEventArgs e)
        {
            OnCars(e);
        }
    }


    public class NewCarsRecevie
    {
        public static void Manager(object sender,NewCarsEventArgs e)
        {
            Console.WriteLine($"通知:新车{e.NewCardName}到了!");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            NewCarsPublisher newCarsPublisher = new NewCarsPublisher();
            newCarsPublisher.Cars += NewCarsRecevie.Manager;
            Console.WriteLine("请输入到达车辆的名称:");
            string name=Console.ReadLine();
            Console.WriteLine("到达车辆是否是新车(Y/N):");
            string answer = Console.ReadLine();
            if (answer=="Y")
            {
                NewCarsEventArgs newCarsEventArgs = new NewCarsEventArgs() { NewCardName=name};

               newCarsPublisher.NewCarsArrivals(newCarsEventArgs);
            }
            else
            {
                Console.WriteLine("不是新车不对订阅者发送通知!");
            }
        }
}   

谨记,事件基于委托,为委托提供了一种发布/订阅机制。理解发布订阅机制就会容易多了。一旦理清楚,发现好像也并不是很难的。多多消化一下,自己动手去想一下实例。去写一下。很快能掌握的。

总结

  委托与事件到这里就大结局了。一些列的问题也解决了。心中的疑惑也揭开了。下面我们就接着基础系列写其他的了。

  曾经,我们懵懵懂懂地看完了狮子王,知道有个勇敢坚强的小狮子叫辛巴。

  现在,跨过山和大海,也走过人山人海,经历了跌跌撞撞,也遭遇了遗憾离别,我们才发现,其实辛巴就是我们每一个自己。

25年前看懂的是剧情,25年后读懂的却是人生……

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 依赖注入容器-- Autofac

    Autofac---Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上非常高...

    小世界的野孩子
  • 面向对象三大特性-----封装、继承、多态

      前面有文章写到了面向对象编程和面向对象设计的头五大原则(SOLID五大原则)。今天我们再来谈谈面向对象的三大特性--封装、继承、多态

    小世界的野孩子
  • .NET Core使用Quartz执行调度任务进阶

    Quartz.Net是一个强大、开源、轻量的作业调度框架,在平时的项目开发当中也会时不时的需要运用到定时调度方面的功能,例如每日凌晨需要统计前一天的数据,又或...

    小世界的野孩子
  • .NET基础拾遗(4)委托、事件、反射与特性

      委托这个概念对C++程序员来说并不陌生,因为它和C++中的函数指针非常类似,很多码农也喜欢称委托为安全的函数指针。无论这一说法是否正确,委托的的确确实现了和...

    Edison Zhou
  • .Net 从零开始构建一个框架之基本实体结构与基本仓储构建

    本系列文章将介绍如何在.Net框架下,从零开始搭建一个完成CRUD的Framework,该Framework将具备以下功能,基本实体结构(基于DDD)、基本仓储...

    郑小超.
  • 在C#/.NET应用程序开发中创建一个基于Topshelf的应用程序守护进程(服务)

    在上一篇文章《C#/.NET基于Topshelf创建Windows服务程序及服务的安装和卸载》中,我们了解发C#/.NET创建基于Topshelf Window...

    Rector
  • 见到了“公司”定义一个Company类,那么见到了“字段”是不是也可定义一个Column类?

      既然见到了公司,我们可以定义一个Class Company ,那么我们见到了字段,是不是也可以定义一个Class ColumnInfo呢? 公司的描述信息类...

    用户1174620
  • C# Command命令(行为型模式)+队列 实现事务,带异步命令重试机制和生命周期

    耦合是软件不能抵御变变化的根本性原因,不仅实体对象与实体对象之间有耦合关系(如创建性设计模式存在的原因),对象和行为之间也存在耦合关系.

    郑小超.
  • APK安装流程详解1——有关"安装ing"的实体类概述

    该类包含了从AndroidManifest.xml文件中收集的所有信息。 PackageInfo.java源码地址 通过源码我们知道PackageInfo是...

    隔壁老李头
  • Facade外观模式(结构性模式)

    需求:开发一个坦克模拟系统用于模拟坦克车在各种作战环境中的行为,其中坦克系统由引擎、控制器、车轮等各子系统构成.然后由对应的子系统调用.

    郑小超.

扫码关注云+社区

领取腾讯云代金券