事件(C#)

类或者对象可以通过事件向其它类或者对象通知发生相关的事情。发送(或引发)事件的类称为“发布者”,接收(或处理)事件的类称为“订阅者”。

事件的属性特征:
1.发行者确定何时引发事件;订户确定对事件做出何种响应。
2.一个事件可以拥有多个订户;订户可以处理来自多个发行者的多个事件。
3.没有订户的事件永远也不会引发。
4.事件通常表示用户的操作,例如单击按钮或者图形用户界面中的菜单栏选项。
5.当事件具有多个订户时,引发事件时会同步调用事件处理程序。
6. 在.NET Framework类库中,事件基于EventHandler委托和EventArgs基类(.NET Framework类库中的所有事件均基于EventHandler委托)。

符合.NET准则的事件
定义如下:

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

**注意:**在.NET Framework 2.0引入了泛型版本的委托EventHandler<TEventArgs>EventHandler和泛型EventHandler<TEventArgs>均为委托类型。
尽管定义的类中的事件可基于任何有效委托类型,甚至是返回值的委托。但一般还是建议使用EventHandler,使事件基于.NET模式。
名称EventHandler可能会造成一些混淆,因为它不会实际处理事件。其签名与委托定义匹配的方法或Lambda表达式事件处理程序,并将在引发事件时调用。
发布基于EventHandler模式的事件
1.将自定义数据的类声明为对发布服务器和订阅者类均为可见的范围。然后添加所需成员以保留自定义事件数据。在下面的示例中,将返回一个简单的字符串。

internal class CustomEventArgs : EventArgs
{
    public CustomEventArgs(string message)
    {
        this.Message = message;
    }
    public string Message { get; set; }
}

2.声明发布类中的委托(若使用的是EventHandler<TEventArgs>泛型版本,请忽略此步骤)。命名通常指定为以EvengHandler结尾的名称。第二个参数指定为自定义EventArgs子类的类型。

public delegate void CustomEventHandler(object sender, CustomEventArgs args);

3.使用下列步骤之一来声明发布类中的事件。
如果没有自定义EventArgs类,事件类型将为非泛型的EventHandler委托。在C#中,不需要声明该委托,因为在创建C#项目时,已经包括在System命名的空间中。将下列代码添加到发布服务器类。

public event EventHandler RaiseCustomEvent;

如果使用非泛型版本EventHandler,并且具有派生自EventArgs的自定义类,请声明发布类中的事件,并将步骤2中的委托用作类型。

public event CustomEventHandler RaiseCustomEvent;

如果使用泛型版本,则无需自定义委托。只需在发布类中,将事件类型指定为EventHandler<CustomEventArgs>,尖括号中替换为自定义的类型名称。

public event EventHandler<CustomEventArgs> RaiseCustomEvent;

下例通过自定义EventArgs类和EventHandler<TEventArgs>作为事件类型演示上述的步骤。

public class UserCustomizeEvent
    {

        public UserCustomizeEvent()
        {
            var pub = new Publisher();
            var Sub = new Subscriber("调用者1", pub);
            var Sub_2 = new Subscriber("调用者2", pub);
            //调用引发事件的方法
            pub.DoSomething();
        }

        //事件订阅者
        internal class Subscriber
        {
            private readonly string _id;

            public Subscriber(string id, Publisher pub)
            {
                this._id = id;
                pub.RaiseCustomEvent += HandleCustomEvent;
            }

            private void HandleCustomEvent(object sender, CustomEventArgs e)
            {
                Console.WriteLine($"{_id}接收到的消息为:{e.Message}");
            }
        }

        //事件发布者
        internal class Publisher
        {
            //声明事件使用EventHandler<T>
            public event EventHandler<CustomEventArgs> RaiseCustomEvent;
            public Publisher()
            {

            }
            public void DoSomething()
            {
                OnRaiseCustomeEvent(new CustomEventArgs("事件触发器开始触发,"));
            }

            protected virtual void OnRaiseCustomeEvent(CustomEventArgs e)
            {
                EventHandler<CustomEventArgs> raiseEvent = RaiseCustomEvent;
                if(raiseEvent != null)
                {
                    e.Message += $"触发的时间为:{DateTime.Now}";
                    raiseEvent(this, e);
                }
            }
        }

        //自定义事件类型,保留自定义事件数据
        internal class CustomEventArgs : EventArgs
        {
            public CustomEventArgs(string message)
            {
                this.Message = message;
            }
            public string Message { get; set; }
        }
    }

总结
1.事件通过event关键字修饰,且通过委托类型进行定义。
2.类或者对象通过事件向其它类或者对象通知发生相关的事情。
3.发生(或引发)事件的类称为“发布者”;接收(或处理)事件的类称为“订阅者”。
4.事件的六大属性特征。
5.标准的.NET委托有EventHandler和泛型类EventHandler<TEventArgs>(.NET Framework 2.0引入),它们均为委托类型。
6.在.NET Framework中,事件基于EventHandler委托和EventArgs基类。
7.在使用泛型类EventHandler<TEventArgs>作为事件类型定义时,无需声明委托类型;否则,需要对委托类型进行声明,并使用声明的委托类型进行声明事件。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值