zoukankan      html  css  js  c++  java
  • C#事件

    转自:http://www.cnblogs.com/ArmyShen/archive/2012/08/31/2664743.html

    事件的四个步骤:

    (1)在事件发行者中定义一个事件

    //声明一个事件,首先要声明一个和事件关联的委托类型
    //声明delegate时,其返回值必须为void类型
    public delegate void DelegateAccount(string info); public delegate void DelegateSales(string info);
    //根据前面声明的委托类型,声明事件
    //事件的声明使用event关键字,后面是委托类型和事件名称 public event DelegateAccount OnAccount; public event DelegateSales OnSales;

    (2)在事件发行者中触发事件

    复制代码
    public void sendAccountInfo()
    {
      //判断事件是否为空
      if (OnAccount != null)
      {
        OnAccount("账单信息");//触发事件,本质上其实就是触发一个委托链
      }
    }
    
    public void sendSalesInfo()
    {
      //判断事件是否为空
      if (OnSales != null)
      {
        OnSales("双倍积分优惠信息");//触发事件,本质上其实就是触发一个委托链
      }
    }
    复制代码

    (3)在事件订阅者中定义事件处理程序

    复制代码
    //收到事件后的处理程序(事件处理程序的类型必须和发行者类中对应的委托一致)
    public void ReceiveAccountInfo(string name)
    {
      Console.WriteLine(UserName + "收到" + name);
    }
    
    public void ReceiveSalesInfo(string name)
    {
      Console.WriteLine(UserName + "收到" + name);
    }
    复制代码

    (4)向事件发行者订阅事件

    复制代码
    //向事件发行者订阅事件
    //订阅一个事件使用"+=",取消一个事件使用"-=",和委托链的使用相同 //委托本身属于静态类型,所以只能用类名调用 bank.OnAccount += new Bank.DelegateAccount(user_A.ReceiveAccountInfo); bank.OnSales += new Bank.DelegateSales(user_A.ReceiveSalesInfo); bank.OnAccount += new Bank.DelegateAccount(user_B.ReceiveAccountInfo); bank.OnSales += new Bank.DelegateSales(user_B.ReceiveSalesInfo);
    复制代码

    完整的事件例子

    复制代码
    using System;
    using System.Collections;
    
    //简单的事件机制
    //比如,我有某个银行的信用卡,我会向银行订阅每期的账单信息和相关优惠信息到手机上
    namespace EventDemo
    {
        //声明一个事件的发行者
        public class Bank
        {
            //事件是通过委托的方式实现的,所以需要先定义一个委托类型
            public delegate void DelegateAccount(string cardInfo);//账单信息委托
            public delegate void DelegateSales(string cardInfo);//优惠信息委托
    
            //事件的声明使用event关键字,后面是委托类型和事件名称
            public event DelegateAccount OnAccount;//账单信息事件
            public event DelegateSales OnSales;//促销信息事件
    
            //账单信息事件的触发方法
            public void sendAccountInfo()
            {
                //判断事件是否为空
                if (OnAccount != null)
                {
                    OnAccount("账单信息");//触发事件,本质上其实就是触发一个委托链
                }
            }
    
            //促销优惠信息事件的触发方法
            public void sendSalesInfo()
            {
                //判断事件是否为空
                if (OnSales != null)
                {
                    OnSales("双倍积分优惠信息");//触发事件,本质上其实就是触发一个委托链
                }
            }
    
        }
    
        //声明一个事件订阅者
        public class User
        {
            private string UserName;
            public User(string name)
            {
                UserName = name;
            }
            //收到事件后的处理程序(事件处理方法的类型必须和发行者类中对应的委托一致)
            public void ReceiveAccountInfo(string cardInfo)
            {
                Console.WriteLine(UserName + "收到" + cardInfo);
            }
    
            public void ReceiveSalesInfo(string cardInfo)
            {
                Console.WriteLine(UserName + "收到" + cardInfo);
            }
        }
    
        class MainFun
        {
            static void Main()
            {
                Bank bank = new Bank();
                User user_A = new User("用户A");
                User user_B = new User("用户B");
    
                //用户向银行订阅账单信息(向事件发行者订阅事件)
                //委托本身属于静态类型,所以只能用类名调用
                bank.OnAccount += new Bank.DelegateAccount(user_A.ReceiveAccountInfo);
                bank.OnSales += new Bank.DelegateSales(user_A.ReceiveSalesInfo);
    
                bank.OnAccount += new Bank.DelegateAccount(user_B.ReceiveAccountInfo);
                bank.OnSales += new Bank.DelegateSales(user_B.ReceiveSalesInfo);
    
                //银行在某个时段向订阅用户发送信息
                bank.sendAccountInfo();
                bank.sendSalesInfo();
    
                //用户可以取消订阅
                bank.OnSales -= new Bank.DelegateSales(user_B.ReceiveSalesInfo);
    
                Console.WriteLine();
    
                //银行再发送相关信息的时候,将不会发送给取消订阅的用户
                bank.sendAccountInfo();
                bank.sendSalesInfo();
            }
        }
    }
    复制代码

    使用<.NET Framework事件设计准则>重写上述代码

    (1)delegate的返回类型必须是void,并以EventNameEventHandler方式命名:EventName是事件的名称,EventHandler是设计准则要求的统一书写方式。

    (2)delegate接受两个参数,参数名必须统一命名为sender和e;第一个参数类型是object,第二个参数是事件的数据类,数据类以EventNameEventArgs命名,并且需继承于System.EventArgs类。

    (3)如果在事件中不需要传递任何数据,也需要声明两个参数:第一个参数就是默认的object sender,第二个参数可以使用系统默认的System.EventArgs类。

    public delegate void EventNameEventHandler(object sender, EventNameEventArgs e);
    public event EventNameEventHandler EventName;
    //委托的声明:使用delegate关键字,后面是void无符号返回类型,之后是EventNameEventHandler,最后是参数列表
    public delegate void CardAccountEventHandler(object sender, CardEventArgs e); public delegate void CardSalesEventHandler(object sender, CardEventArgs e);//事件的声明:使用event关键字,后面是委托名称和EventName public event CardAccountEventHandler CardAccount; public event CardSalesEventHandler CardSales;

    (4)在触发事件的类中提供一个受保护的方法,以OnEventName命名,在该方法中触发事件:

    复制代码
    //protected关键字:只能在类本身或者子类中使用
    //virtual关键字:虚方法的声明,子类可以对父类中的虚方法进行重写
    protected virtual void OnCardAccount(CardEventArgs e)
    {
      if (CardAccount != null)
      {
        CardAccount(this, e);
      }
    }
    ...
    复制代码

    完整代码:

    复制代码
    using System;
    using System.Collections;
    
    //简单的事件机制
    //比如,我有某个银行的信用卡,我会向银行订阅每期的账单信息和相关优惠信息到手机上
    namespace EventDemo
    {
        //事件数据类
        public class CardEventArgs : EventArgs
        {
            private string cardInfo;
            public CardEventArgs(string info)
            {
                cardInfo = info;
            }
            public string CardInfo
            {
                get { return cardInfo; }
            }
        }
        //事件的发行者
        public class Bank
        {
            public delegate void CardAccountEventHandler(object sender,  CardEventArgs e);//账单信息委托
            public delegate void CardSalesEventHandler(object sender, CardEventArgs e);//优惠信息委托
    
            public event CardAccountEventHandler CardAccount;//账单信息事件
            public event CardSalesEventHandler CardSales;//促销信息事件
        
         //此方法用于触发事件 protected virtual void OnCardAccount(CardEventArgs e) { //声明一个临时的委托(查阅资料说这样写可以避免可能出现的线程同步问题) CardAccountEventHandler handler = CardAccount; if (handler != null) { handler(this, e); } } protected virtual void OnCardSales(CardEventArgs e) { CardSalesEventHandler handler = CardSales; if (handler != null) { handler(this, e); } }
         //这里调用事件触发   public void sendAccountInfo(string cardInfo) { Console.WriteLine(cardInfo); //事件在这里被触发 OnCardAccount(new CardEventArgs(cardInfo)); } public void sendSalesInfo(string cardInfo) { Console.WriteLine(cardInfo); OnCardSales(new CardEventArgs(cardInfo)); } } //事件订阅者 public class User { private string UserName; public User(string name) { UserName = name; } //收到事件后的处理程序(事件处理方法的类型必须和发行者类中对应的委托一致) public void ReceiveAccountInfo(object sender, CardEventArgs e) { Console.WriteLine(UserName + "收到" + e.CardInfo); } public void ReceiveSalesInfo(object sender, CardEventArgs e) { Console.WriteLine(UserName + "收到" + e.CardInfo); } } class MainFun { static void Main() { Bank bank = new Bank(); User user_A = new User("用户A"); User user_B = new User("用户B"); //用户向银行订阅账单信息(向事件发行者订阅事件) //委托本身属于静态类型,所以只能用类名调用 bank.CardAccount += new Bank.CardAccountEventHandler(user_A.ReceiveAccountInfo); bank.CardSales += new Bank.CardSalesEventHandler(user_A.ReceiveSalesInfo); bank.CardAccount += new Bank.CardAccountEventHandler(user_B.ReceiveAccountInfo); bank.CardSales += new Bank.CardSalesEventHandler(user_B.ReceiveSalesInfo); //银行在某个时段向订阅用户发送信息 bank.sendAccountInfo("账单信息"); bank.sendSalesInfo("双倍积分"); //用户可以取消订阅 bank.CardSales -= new Bank.CardSalesEventHandler(user_B.ReceiveSalesInfo); Console.WriteLine(); //银行再发送相关信息的时候,将不会发送给取消订阅的用户 bank.sendAccountInfo("账单信息"); bank.sendSalesInfo("双倍积分"); } } }
  • 相关阅读:
    UDK Stat命令
    绝地求生-全军出击手游
    UE3中的时间
    Git原理与命令大全
    【SpringCloud】Spring Cloud Alibaba 之 Nacos注册中心(二十七)
    【SpringCloud】Spring Cloud Alibaba 及 Nacos介绍(二十六)
    【Web】Keepalived+Nginx 实现高可用集群
    【SpringCloud】Spring Cloud Sleuth + Zipkin + RabbitMQ 集成(二十五)
    【SpringCloud】Spring Cloud Sleuth 日志跟踪(二十六)
    Spring框架学习笔记(5)——Spring Boot创建与使用
  • 原文地址:https://www.cnblogs.com/cugwx/p/4059923.html
Copyright © 2011-2022 走看看