C# event 事件

0.前言

事件是对象用于(向系统中的所有相关组件)广播已发生事情的一种方式。 任何其他组件都可以订阅事件,并在事件引发时得到通知,在设计模式中叫做观察者模式。和委托类似,事件是后期绑定机制。 用于定义事件以及订阅或取消订阅事件的语法是对委托语法的扩展。

1.事件的使用

在C# GUI程序中,事件处理是很常用的,比如C# WPF中一个按钮的点击,可以对应到一个事件处理方法:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Console.WriteLine(sender.ToString() + ":" + e.ToString());
        }

在类的内部声明事件,需要先有一个委托类型。然后,使用event定义一个成员(使用event关键字后,这个委托类型的字段就不能使用=赋值,只能+=或者-=)。其实操作流程和委托差不多,下面的代码定义了一个Sender和一个Receiver类,Sender的事件被传递给Receiver,然后执行事件处理方法。

using System;

namespace TestCS_20191117_event
{
    class Program
    {
        static void Main(string[] args)
        {
            Sender sender = new Sender();
            Receiver receiver = new Receiver();

            sender.AHandler += receiver.OnAChanged;
            sender.BHandler += receiver.OnBChanged;
            sender.CHandler += receiver.OnCChanged;
            sender.SomeChange();

            Console.ReadKey();
        }
    }

    class Sender
    {
        //1. 使用自定义的delegate
        public delegate void MyEventHandler(string arg);
        public event MyEventHandler AHandler;

        //2. 使用EventHandler
        public class MyArgs:System.EventArgs
        {
            public MyArgs(string arg)
            {
                Arg = arg;
            }
            public string Arg { get; set; }
        }
        //注意,赋值了一个空委托,这样就不必检查是否有接收者(调用前判断null)
        public event EventHandler<MyArgs> BHandler = delegate { };

        //3. 声明泛型委托类型 
        //(where指定约束类型)
        public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e)
            where TEventArgs : EventArgs;
        //使用上面定义的MyArgs:System.EventArgs来实例化
        public event EventHandler<MyArgs> CHandler = delegate { };


        //想要引发事件时,使用委托调用语法调用事件处理程序
        public void SomeChange()
        {
            AHandler?.Invoke("AHandler");
            BHandler?.Invoke(this, new MyArgs("BHandler"));
            CHandler?.Invoke(this, new MyArgs("CHandler"));
        }
    }

    class Receiver
    {
        public void OnAChanged(string arg)
        {
            System.Console.WriteLine("a changed:" + arg);
        }
        public void OnBChanged(object sender,Sender.MyArgs arg)
        {
            System.Console.WriteLine("b changed:" + arg.Arg);
        }
        public void OnCChanged(object sender, Sender.MyArgs arg)
        {
            System.Console.WriteLine("c changed:" + arg.Arg);
        }
    }
}

2.使用委托完成观察者模式

如果没有事件,我们可以通过多播委托来实现发布-订阅的一个功能。发布者声明一个委托成员,当数据改变时就调用委托,而委托列表中添加了多个订阅者的回调方法。代码如下:

using System;

namespace TestCS_20191117_event
{
    class Program
    {
        static void Main(string[] args)
        {
            Sender sender = new Sender();
            Receiver receiver = new Receiver();

            sender.TestChang += receiver.OnTestChanged;
            sender.Test = "new test";

            Console.ReadKey();
        }
    }

    class Sender
    {
        public Action<string> TestChang { get; set; }
        private string test;
        public string Test
        {
            get { return test; }
            set
            {
                if (value != test)
                {
                    test = value;
                    // test值改变就调用委托
                    TestChang?.Invoke(value);
                }
            }
        }
    }

    class Receiver
    {
        public void OnTestChanged(string arg)
        {
            System.Console.WriteLine("test changed:" + arg);
        }
    }
}

3.参考

MSDN文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/events-overview

书籍:C#本质论
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龚建波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值