一篇文章带你了解C#的委托与事件(含代码讲解)

2020-02-04 14:19:35  阅读 2366 次 评论 0 条

本文没有任何概念介绍,直接通过代码的方式去讲解


首先,我们要知道,什么情况下要用到委托和事件:

请看下面的一个场景:

学校要组织一场辩论会,挑选了两组学生为代表,一面是正方,一面是反方

然后有一名主持人,主持人会组织让哪一方先发言,主持人说结束双方撤离(举个例子,别杠)

而想要说什么,主持人并不关心

那么,有脑子反应快的同学则会说了:

这个直接用if语句不就行了嘛

    if(A方代表发言)
    {
        A方学生发言
    }
    if(B方代表发言)
    {
        B方学生发言
    }
    if(自由辩论)
    {
        双方劈里啪啦在讲
    }
    if(辩论结束)
    {
        双方撤离
    }


如果真的有这么简单,那我还写这篇文章干嘛呢?

仔细想想,假如是个课堂,学生可能不止一个,这样的话,每个学生都要写一个IF分支?

在辩论会中,学生无需关心发生的其他事情,只等待主持人的发言信号

主持人让发言,就相当于告诉了全部学生,学生们就会根据自己所在的组,进行发言或做其他事情


开始正题

我们首先要定义三个类(可以是多个,想几个都行),分别为主持人(Host),正方(GroupA),反方(GroupB)

    /// <summary>
    /// 主持人
    /// </summary>
    public class Host
    {

    }

    /// <summary>
    /// 正方
    /// </summary>
    public class GroupA
    {

    }

    /// <summary>
    /// 反方
    /// </summary>
    public class GroupB
    {

    }


主持人中有 单方发言  自由辩论  撤离三个方法,其中,单方发言有一个形参,就是哪一方(正方,反方),正方和反方各自有一个发言和撤离方法。

    /// <summary>
    /// 主持人
    /// </summary>
    public class Host
    {
        /// <summary>
        /// 发言
        /// </summary>
        /// <param name="group">组A还是组B</param>
        public void speechDirective(string group)
        {

        }

        /// <summary>
        /// 自由辩论
        /// </summary>
        public void freeDebateDirective()
        {

        }

        /// <summary>
        /// 散场
        /// </summary>
        public void overDirective()
        {

        }
    }

    /// <summary>
    /// 正方
    /// </summary>
    public class GroupA
    {
        /// <summary>
        /// 发言
        /// </summary>
        public void speech()
        {

        }

        /// <summary>
        /// 散场
        /// </summary>
        public void over()
        {

        }
    }

    /// <summary>
    /// 反方
    /// </summary>
    public class GroupB
    {
        /// <summary>
        /// 发言
        /// </summary>
        public void speech()
        {

        }

        /// <summary>
        /// 散场
        /// </summary>
        public void over()
        {

        }
    }

到此,三个类已经构造完毕,

那么,怎样让两方根据主持人的指令去发言呢?

我们要在主持人中,采用一种方法,把指令传出去,

在主持人之前,我们要跟别定义一个

带形参的发言委托SpeechEventHanlder

不带形参的自由辩论委托FreeDebateEventHanlder

不带形参的散场委托OverEventHanlder

命名规则就是传递的方法名后+EventHanlder,不要问我为什么,介绍为什么的文章多的是,可以自行去百度或Google

当然,你也可以不遵循命名规则,对程序的运行和编译无任何影响,只是增加了自己或别人日后阅读代码的难度。

    delegate void SpeechEventHanlder(string group);//发言委托
    delegate void FreeDebateEventHanlder();//自由辩论委托
    delegate void OverEventHanlder();//散场委托

然后在主持人中定义两个事件。这个类似于大家在WinForm中拖出Button双击它即可编辑它的事件。

       public event SpeechEventHanlder Speech;//发言事件
    public event FreeDebateEventHanlder FreeDebate;//自由辩论事件
    public event OverEventHanlder Over;//散场事件

事件定义好之后,我们就可以在主持人中调用这个事件了。那么,如果其他学生订阅了这个事件,便可以自动执行了。

        /// <summary>
        /// 发言
        /// </summary>
        /// <param name="group">组A还是组B</param>
        public void speechDirective(string group)
        {
            Console.WriteLine("主持人:请{0}方代表发言",group);
            //调用发言事件,并传正方还是反方
            if (Speech!=null)
            {
                Speech(group);
            }
        }

        /// <summary>
        /// 自由辩论
        /// </summary>
        public void freeDebateDirective()
        {
            Console.WriteLine("主持人:请双方自由辩论");
            //调用自由辩论事件
            if (FreeDebate!=null)
            {
                FreeDebate();
            }
        }

        /// <summary>
        /// 散场
        /// </summary>
        public void overDirective()
        {
            Console.WriteLine("主持人:辩论会就到这里,散会");
            //调用散会事件
            if (Over!=null)
            {
                Over();
            }
        }

同样,不要问我为什么这么写,按照上述操作即可。一旦熟练这种方法,自然就体会其中含义了。

那么,两方学生们必须知道主持人是谁吧,才能听谁的话,因此,在GroupAGroupB中,都需要声明一个Host,这个声明可以通过GroupA和GroupB的构造函数进行实例化,实例化之后,就可以在GroupA和GroupB中订阅Host中的事件了。

完整代码

    class Program
    {
        public static void Main(string[] args)
        {
            Host host = new Host();
            GroupA a = new GroupA(host);//正方
            GroupB b = new GroupB(host);//反方
            
            
            //host.speechDirective("正");
            //host.speechDirective("反");
            //host.freeDebateDirective();
            host.overDirective();
            Console.ReadLine();
        }
    }
    /// <summary>
    /// 发言委托
    /// </summary>
    /// <param name="group">正/反方</param>
    public delegate void SpeechEventHanlder(string group);
    /// <summary>
    /// 自由辩论委托
    /// </summary>
    public delegate void FreeDebateEventHanlder();
    /// <summary>
    /// 散场委托
    /// </summary>
    public delegate void OverEventHanlder();

    /// <summary>
    /// 主持人
    /// </summary>
    public class Host
    {
        
        public event SpeechEventHanlder Speech;//发言事件
        public event FreeDebateEventHanlder FreeDebate;//自由辩论事件
        public event OverEventHanlder Over;//散场事件

        /// <summary>
        /// 发言
        /// </summary>
        /// <param name="group">组A还是组B</param>
        public void speechDirective(string group)
        {
            Console.WriteLine("主持人:请{0}方代表发言",group);
            //调用发言事件,并传正方还是反方
            if (Speech!=null)
            {
                Speech(group);
            }
        }

        /// <summary>
        /// 自由辩论
        /// </summary>
        public void freeDebateDirective()
        {
            Console.WriteLine("主持人:请双方自由辩论");
            //调用自由辩论事件
            if (FreeDebate!=null)
            {
                FreeDebate();
            }
        }

        /// <summary>
        /// 散场
        /// </summary>
        public void overDirective()
        {
            Console.WriteLine("主持人:辩论会就到这里,散会");
            //调用散会事件
            if (Over!=null)
            {
                Over();
            }
        }
    }

    /// <summary>
    /// 正方
    /// </summary>
    public class GroupA
    {
        Host host;
        public GroupA(Host host)
        {
            this.host = host;
            //开始绑定事件
            host.Speech += new SpeechEventHanlder(a_SpeechEvent);
            host.FreeDebate += new FreeDebateEventHanlder(a_FreeDebateEvent);
            host.Over += new OverEventHanlder(a_OverEvent);
        }

        /// <summary>
        /// 主持人发出的发言指令
        /// </summary>
        /// <param name="group">如果主持人说正方,那么正方发表言论</param>
        void a_SpeechEvent(string group)
        {
            if(group.Equals("正"))
            {
                speech();
            }
        }

        /// <summary>
        /// 主持人发出的自由辩论指令
        /// </summary>
        void a_FreeDebateEvent()
        {
            speech();
        }

        /// <summary>
        /// 主持人发出的散场指令
        /// </summary>
        void a_OverEvent()
        {
            over();
        }

        /// <summary>
        /// 发言
        /// </summary>
        public void speech()
        {
            Console.WriteLine("正方选手正在说话·))");
        }

        /// <summary>
        /// 散场
        /// </summary>
        public void over()
        {
            Console.WriteLine("正方选手撤离现场");
        }
    }

    /// <summary>
    /// 反方
    /// </summary>
    public class GroupB
    {
        Host host;
        public GroupB(Host host)
        {
            this.host = host;
            host.Speech += new SpeechEventHanlder(a_SpeechEvent);
            host.FreeDebate += new FreeDebateEventHanlder(a_FreeDebateEvent);
            host.Over += new OverEventHanlder(a_OverEvent);
        }

        /// <summary>
        /// 主持人发出的发言指令
        /// </summary>
        /// <param name="group">如果主持人说反方,那么反方发表言论</param>
        void a_SpeechEvent(string group)
        {
            if (group.Equals("反"))
            {
                speech();
            }
        }

        /// <summary>
        /// 主持人发出的自由辩论指令
        /// </summary>
        void a_FreeDebateEvent()
        {
            speech();
        }

        /// <summary>
        /// 主持人发出的散场指令
        /// </summary>
        void a_OverEvent()
        {
            over();
        }

        /// <summary>
        /// 发言
        /// </summary>
        public void speech()
        {
            Console.WriteLine("反方选手正在说话·))");
        }

        /// <summary>
        /// 散场
        /// </summary>
        public void over()
        {
            Console.WriteLine("反方选手撤离现场");
        }
    }

写在最后

    近期发现某网站采集本网站的内容,并且不加来源,网址和网站名称我就不贴出来了,1是不想招惹仇家,2是不想给他们做外链。还请你们自重,谢谢


微信扫码查看本文
本文地址:https://www.yangguangdream.com/?id=2066
版权声明:本文为原创文章,版权归 编辑君 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

还没有留言,还不快点抢沙发?