c#编码技巧(六):细究EventHandler和EventHandler<T>的用途与使用场景

假如有一个场景:A类的某个动作/事件,触发了B类的某个响应,一开始可能会想到委托事件:

1.先声明委托

2.再声明事件

3.订阅:A的事件连接B的响应

4.结果:A类的事件触发了,B类的响应也随之触发

(一、普通做法)

1.首先定义一个A类,声明委托、事件

    public class Teacher
    {
        //官方定义:委托是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。
        //个人通俗点的理解:就是长某某样子的函数,如长得类似与"void DeleAct(string name)"--没有返回值带一个参数的函数
        public delegate void DeleAct(string name);     
                                                       
        public event DeleAct ActHandler;    
        public void Come()
        {
            Console.WriteLine("老师来了");
            if (ActHandler != null)
                ActHandler("杨老师");
        }
    }

2.再定义一个响应B类

    public class Students
    {
        public void Action_Teacher(string name)
        {
            Console.WriteLine("全班起立,喊:{0}好", name);
        }
    }

3.然后Main函数里订阅事件,连接两个关联动作

            Teacher teacher = new Teacher();
            Students student = new Students();

            teacher.ActHandler += student.Action_Teacher;

4.再触发A类的动作

            Console.WriteLine("订阅好之后,开始触发动作了");
            teacher.Come();//Come会触发Students的Action_Teacher
            Console.Read();

结果:

订阅好之后,开始触发动作了
老师来了
全班起立,喊:杨老师好

(二、用EventHandler改造)

如果又有一个校长Headmaster类,希望传递更多信息给Students类,比如姓名、获奖数、年龄等呢

或者有另一个青年教师YoungTeacher类,也希望传递更多信息给Students类,比如爱好、毕业院校等呢?

那就要定义多个委托,定义不同的参数类

此时EventHandler就派上用场了,使用它:

(1).不必定义多个不同名字不同类型的委托

(2)搭配EventArgs,可传递多个信息

过程:

1.定义一个参数类HeadArgs,用来传递校长的信息。

注意:必须继承于EventArgs的类,定义时可以包含定义很多字段属性,包含很多信息。

    public class HeadArgs : EventArgs
    {
        public string Name { get; set; }
        public int MedalCount { get; set; }
    }

2.直接声明EventHandler事件,省了声明委托这一步,并且调用时,必须用两个参数(object sender, EventArgs e)。

如ActHandler(null, args),其中args是继承于EventArgs 的HeadArgs。

    public class Headmaster
    {
        public event EventHandler ActHandler;
        public void Come()
        {
            Console.WriteLine("校长来了");

            HeadArgs args = new HeadArgs() { Name = "王校长", MedalCount = 10 };
            ActHandler(null, args);
        }
    }

3.B类的响应事件写一个带object sender, EventArgs e参数的方法

    public class Students
    {
        public void Action_Master(object sender, EventArgs e)
        {
            HeadArgs args = e as HeadArgs;
            Console.WriteLine("全班起立,喊:{0}好", args.Name);
            Console.WriteLine("校长的获奖数是:{0}", args.MedalCount);
        }
    }

4.连接两个关联动作

            Students student = new Students();
            Headmaster master = new Headmaster();

            master.ActHandler += student.Action_Master;

5.触发事件

            Console.WriteLine("-----------------------");
            master.Come();//触发Students的Action_Master
            Console.Read();

结果:

-----------------------
校长来了
全班起立,喊:王校长好
校长的获奖数是:10

(三、用EventHandler<T>改造,简约)

假如王校长只有一个name要传递呢,那就可以使用EventHandler<T>使整个过程更简单。改造如下:

1.定义一个校长类,此处EventHandler<T>中T的类型为string,这样就省略了一个HeadArgs参数类,因为没那么多信息要传递。

    public class Headmaster
    {
        public event EventHandler<string> ActHandler;
        public void Come()
        {
            Console.WriteLine("校长来了");

            ActHandler(null, "王校长");//只传递"王校长"这个string即可
        }
    }

2.Stendent类中,方法的参数为object和string类型

    public class Students
    {
        public void Action_Master(object sender, string name)
        {
            Console.WriteLine("全班起立,喊:{0}好", name);
        }
    }

3.订阅连接

            Students student = new Students();
            Headmaster master = new Headmaster();

            master.ActHandler += student.Action_Master;

4.输出:

            Console.WriteLine("-----------------------");
            master.Come();//触发事件
            Console.Read();

结果:

-----------------------
校长来了
全班起立,喊:王校长好

总结:使用EventHandler

(1).标准化,代码美观统一;

(2)可省略定义委托这一步。不必定义多个不同类型的委托;

(2)搭配EventArgs,可传递多个信息。

  • 22
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值