C#中的事件

一.什么是事件

事件涉及两类角色——事件的发布者和事件的订阅者,当某个事件发生后,事件发布者会发布消息;事件订阅者会接收到事件已发生的通知,并做出相应处理。其中,触发事件的对象成为事件发布者,捕获事件并对其做出处理的对象成为事件订阅者。

二.如何定义事件

在C#中定义事件,与定义类成员非常相似,仅需要另外包含一个event关键字即可,如下所示:

public evnet EvnetHandler birthday

事件的定义结构为:

访问修饰符 event 委托类型 事件名;

事件定义中还包含委托类型,它既可以是自定义的委托类型,也可以是.NET类库中预定义的委托类型EventHandler。

三.订阅和取消事件

事件订阅者需要订阅事件发布者发布的事件,以便在事件被触发时接收到消息并做出处理;可以使用“+=”运算符来订阅事件,使用“-=”运算符来取消事件订阅。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Evnet
{
    //新郎官类充当事件的发布者角色
    public class BridegRoom
    {
        //自定义委托
        public delegate void MarryHandler(string msg);

        //使用自定义委托类型定义事件,事件名为MarryEvent
        public event MarryHandler MarryEvent;

        //发出事件
        public void OnMarriageComing(string msg)
        {
            //判断是否绑定了事件处理方法
            if(MarryEvent != null)
            {       
                //触发事件
                MarryEvent(msg);
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Evnet
{
    //朋友类,事件订阅者
    public class Friend
    {
        //字段
        public string _name;

        //构造函数
        public Friend(string name)
        {
            _name = name;
        }

        //事件处理函数,该函数需要符合MarryHandler委托的定义
        public void SendMessage(string message)
        {
            //输出通知信息
            Console.WriteLine(message);
            //对事件做出处理
            Console.WriteLine(this._name + "收到了,到时候准时参见");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Evnet
{
    class Program
    {
        public event EventHandler e;
        static void Main(string[] args)
        {
            //初始化新郎官对象
            BridegRoom br = new BridegRoom();

            //实例化朋友对象
            Friend f1 = new Friend("陈三");
            Friend f2 = new Friend("李四");
            Friend f3 = new Friend("王五");

            //使用“+=”来订阅事件
            br.MarryEvent += new BridegRoom.MarryHandler(f1.SendMessage);
            br.MarryEvent += new BridegRoom.MarryHandler(f2.SendMessage);

            //发出通知,此时只有订阅了事件的对象才能收到通知
            br.OnMarriageComing("朋友们,我结婚了,到时候准时参加婚礼!");
            Console.WriteLine("---------------------------------------");

            //使用“-=”来取消事件的订阅,此时李四收不到信息
            br.MarryEvent -= new BridegRoom.MarryHandler(f2.SendMessage);

            //使用“+=”来取消订阅事件,此时王五可以收到通知
            br.MarryEvent += new BridegRoom.MarryHandler(f3.SendMessage);

            //发出通知
            br.OnMarriageComing("朋友们,我结婚了,到时候准时参加婚礼!");
            Console.ReadKey();

        }
    }
}

四.使用.NET类库汇总预定义的委托类型EventHandler来定义事件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyEventHandler
{
    //新郎官类,事件发布者角色
    public class BridegRoom
    {
        //使用.NET类库中预定义的委托类型EventHandler来定义事件
        public event EventHandler MarryEvent;

        //发出事件
        public void OnBirthdayComing(string msg)
        {
            //判断是否绑定了事件处理方法
            if (MarryEvent != null)
            {
                Console.WriteLine(msg);

                //触发事件
                MarryEvent(this, new EventArgs());
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyEventHandler
{
    //朋友类 事件订阅者
    public class Friend
    {
        //字段
        public string _name;

        public Friend(string name)
        {
            _name = name;
        }

        //事件处理函数,该函数需要符合EventHandler委托定义
        public void SendMessage(object s, EventArgs e)
        {
            //对事件做出处理
            Console.WriteLine(this._name + "收到了,到时候准时参加");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyEventHandler
{
    class Program
    {
        static void Main(string[] args)
        {
            //初始化新郎官对象
            BridegRoom br = new BridegRoom();

            //实例化朋友对象
            Friend f1 = new Friend("张三");
            Friend f2 = new Friend("李四");
            Friend f3 = new Friend("王五");

            //使用“+=”来订阅事件
            br.MarryEvent += new EventHandler(f1.SendMessage);
            br.MarryEvent += new EventHandler(f2.SendMessage);

            //发出通知,此时只有订阅了事件的对象才能收到通知
            br.OnBirthdayComing("朋友们,我结婚了,到时候准时参加婚礼!");
            Console.WriteLine("----------------------------------------");

            //使用“-=”来取消事件订阅,此时李四将收不到通知
            br.MarryEvent -= new EventHandler(f2.SendMessage);

            //使用“+=”来订阅事件,此时王五可以收到通知
            br.MarryEvent += new EventHandler(f3.SendMessage);

            //发出通知
            br.OnBirthdayComing("朋友们,我结婚了,到时候准时参加婚礼!");
            Console.ReadKey();

        }
    }
}

EventHandler是.NET类库中预定义的委托类型,用于处理不包含事件数据的事件,如果想在事件中包含事件数据,可以通过派生EventArgs来实现,它的具体定义如下:

public delegate void EventHandler(object sender, EventArgs e);

从EventHandler委托的定义可以看出:

(1).该委托的返回类型为void,因此实例化委托类型的方法也需要满足这点;

(2).第一个参数sender负责保存对触发事件对象的引用,其类型为object;

(3).第二个参数e负责保存事件数据,EventArgs类也是.NET类库中定义的类,它不保存任何数据。

五.扩展EventArgs类

因为EventHandler只用于处理不包含事件数据的事件,如果我们想要在由这种方式定义的事件中包含事件数据,则可以通过派生EvnetArgs类来实现。下面通过扩展EvnetArgs类来使事件参数e带有事件数据。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyEventHandler
{
    //自定义事件类,并使其带有事件数据
    public class MarryEventArgs:EventArgs
    {
        public string _messsage;
        public MarryEventArgs(string msg)
        {
            _messsage = msg;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyEventHandler
{
    //新郎官类,事件发布者角色
    public class BridegRoom
    {
        //自定义委托类型,委托包含两个参数
        public delegate void MarryHandler(object sender, MarryEventArgs e);

        //定义事件
        public event MarryHandler MarryEvent;

        //发出事件
        public void OnBirthdayComing(string msg)
        {
            //判断是否绑定了事件处理的方法
            if(MarryEvent != null)
            {
                //触发事件
                MarryEvent(this, new MarryEventArgs(msg));
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyEventHandler
{
    //朋友类 事件订阅者
    public class Friend
    {
        //字段
        public string _name;

        public Friend(string name)
        {
            _name = name;
        }

        //事件处理函数,该函数需要符合EventHandler委托定义
        public void SendMessage(object s, MarryEventArgs e)
        {
            //输出通知信息
            Console.WriteLine(e._messsage);

            //对事件做出处理
            Console.WriteLine(this._name + "收到了,到时候准时参加");
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyEventHandler
{
    class Program
    {
        static void Main(string[] args)
        {
            //初始化新郎官对象
            BridegRoom br = new BridegRoom();

            //实例化朋友对象
            Friend f1 = new Friend("张三");
            Friend f2 = new Friend("李四");
            Friend f3 = new Friend("王五");

            //使用“+=”来订阅事件
            br.MarryEvent += new BridegRoom.MarryHandler(f1.SendMessage);
            br.MarryEvent += new BridegRoom.MarryHandler(f2.SendMessage);

            //发出通知,此时只有订阅了事件的对象才能收到通知
            br.OnBirthdayComing("朋友们,我结婚了,到时候准时参加婚礼!");
            Console.WriteLine("----------------------------------------");

            //使用“-=”来取消事件订阅,此时李四将收不到通知
            br.MarryEvent -= new BridegRoom.MarryHandler(f2.SendMessage);

            //使用“+=”来订阅事件,此时王五可以收到通知
            br.MarryEvent += new BridegRoom.MarryHandler(f3.SendMessage);

            //发出通知
            br.OnBirthdayComing("朋友们,我结婚了,到时候准时参加婚礼!");
            Console.ReadKey();

        }
    }
}

以上代码通过自定义MarryEventArgs事件类扩展了EventArgs类,此时MarryEventArgs带有一个名为Message的事件参数;然后订阅对象的SendMessage方法中,通过e.Message的方式获得了事件数据,并把事件数据输出。

转载于:https://www.cnblogs.com/QingYiShouJiuRen/p/11152511.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值