C#語法學習事件(Event)

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/2
 * Time: 下午 11:39
 * 事件(event)
 * 
 * 事件是類在發生其關注的事情時用來提供通知的一种方式.
 * 例如,封裝用戶界面控件的類可以定義一個在用戶單擊該控件時發生的事件.
 * 控件類不關心單擊按鈕時發生了什麼,但它需要告知派生類單擊事件已發生.
 * 然後,派生類可選擇如何響應.
 * 
 * 事件有兩個角色
 * 事件發行者(Publisher):
 * 一個事件發行者,也稱作發送者(sender),其實就是一個對像.
 * 這個對像會自行維掮本身的狀態信息.
 * 當本身狀態信息變動時,便觸發一個事件,並通知所有的事件訂閱者.
 * 事件訂閱者(Subscriber):
 * 對事件感興趣的對像,也稱為接收者(Receiver),可以註冊感興趣的事件.
 * 通常需提供一個事件處理程序,在事件發行者觸發一個事件後,
 * 會自動執行這段代碼的內容.
 * 
 * 
 
*/
 
using  System;
 
class  Publisher // 出版社
 {
     
public   delegate   void  Publish(); // 聲明事件所需的代理
      public   event  Publish OnPublish; // 事件的聲明
      public   void  issue() // 觸發事件的方法
     {
         
if (OnPublish != null )
         {
             Console.WriteLine(
" 發行刊物 " );
             OnPublish();
         }
     }
 }
 
class  Subscriber // 訂閱者
 {
     
public   void  Receive() // 在事件訂閱者中定議事件處理程序
     {
         Console.WriteLine(
" 訂閱者已經收到刊物 " );    
     }
 }
 
class  Story
 {
     
static   void  Main()
     {
         Publisher Pub
= new  Publisher();
         Subscriber zs
= new  Subscriber();
         Pub.OnPublish
+= new  Publisher.Publish(zs.Receive); // 向事件發行者訂閱一個事件
         Pub.issue(); // 觸發事件
     }
 }

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/2
 * Time: 下午 11:39
 * 事件(event)
 * 
 * 
 * 事件的四個步驟
 * 1,在事件發行者中定議一個事件
 * 2,在事件發行者中觸發事件
 * 3,在事件訂閱者中定議事件處理程序
 * 4,向事件發行者訂閱一個事件
 
*/
 
using  System;
 
class  Publisher // 出版社
 {
     
public   delegate   void  PubComputer( string  magazineName); // 聲明事件所需的代理
      public   delegate   void  PubLife( string  magazineName);
     
public   event  PubComputer OnPubComputer;
     
public   event  PubLife OnPubLife; // 事件的聲明
      public   void  issueComputer() // 觸發事件的方法
     {
         
if (OnPubComputer != null )
         {
             Console.WriteLine(
" 發行<<電腦>>雜志 " );
             OnPubComputer(
" 電腦雜志 " );
         }
     }
     
public   void  issueLife()
     {
         
if (OnPubLife != null )
         {
             Console.WriteLine(
" 發行<<生活>>雜志 " );
             OnPubLife(
" 生活雜志 " );
         }
     }
 }
 
class  Subscriber // 訂閱者
 {
     
private   string  name;
     
public  Subscriber( string  name_)
     {
         
this .name = name_;
     }
     
public   void  Receive( string  magazineName) // 在事件訂閱者中定議事件處理程序
     {
         Console.WriteLine(name 
+   " 已經收到 "   +  magazineName);    
     }
 }
 
class  Story
 {
     
static   void  Main()
     {
         
// 事件發行者只會把事件發關給訂閱的用戶
         Publisher Pub = new  Publisher();
         Subscriber zs
= new  Subscriber( " 張三 " );
         Pub.OnPubComputer
+= new  Publisher.PubComputer(zs.Receive); // 向事件發行者訂閱一個事件
         Subscriber ls = new  Subscriber( " 李四 " );
         Pub.OnPubComputer
+= new  Publisher.PubComputer(ls.Receive);
         Pub.OnPubLife
+= new  Publisher.PubLife(ls.Receive);
         Pub.issueComputer();
         Pub.issueLife();
         Console.WriteLine();
         Console.WriteLine(
" 一年以後李四不再訂閱<<電腦>>雜志 " );
         Pub.OnPubComputer
-= new  Publisher.PubComputer(ls.Receive);
         Pub.issueComputer();
         Pub.issueLife();        
     }
 }

/*
 * Created by SharpDevelop.
 * User: Administrator
 * Date: 2008/9/2
 * Time: 下午 11:39
 * 事件(event)
 * 
 * .NET Framework事件設計準則
 * 1,事件的命名準則使用PascalCasing命名方式
 * 2,聲明delegate時,使用void類型當作返回值,EventName事件的事件
 * 委托是EventNameEventHandler,事件接受兩個傳入參數,一力命名為
 * sender與e.
 * 3,定議一個提供中件數據的類.對類以EventNameEventArgs進行命名,
 * 從System.EventArgs派生該類,然後添加所有事件特定的成員.
 * 
 * public delegate vodi EventNameEventHandler(object sender,EventNameEventArgs e);
 * 
 * 下面的過程說明如何在婁中實現事件.如果事件不需要傳遞
 * 任何數據,也要聲明兩個參數,e參數可以直接使用系統提供
 * 的System.EventArgs類.如果需要傳遞數據,則要從
 * System.EventArgs繼承一個類,並把數據放在里面.
 * public delegate void EventNameEventHandler(object sender,EventArgs e);
 * public event EventNameEventHandler EventName;
 * 
 * 
 * 在引發事件的類中提供一個受保護的方法.
 * [主要是為了防止線程同步]
 * 以OnEventName進行命名.在該方法中引發該事件
 * protected virtual void OnEventName(EventArgs e)
 * {
 *     if(EventName!=null)
 *     {
 *         EventName(this,e);
 *     }
 * }
 * 下面我們就按設計準則來改寫前一個例子.
 
*/
 
using  System;
 
class  PubEventArgs : EventArgs
 {
     
private   readonly   string  _magazinename;
     
private   readonly  DateTime _pubdate;
     
public  PubEventArgs( string  magazineName,DateTime pubDate)
     {
         
this ._magazinename = magazineName;
         
this ._pubdate = pubDate;
     }
     
public   string  magazineName
     {
         
get  {  return   this ._magazinename; }
     }
     
public  DateTime pubDate
     {
         
get return   this ._pubdate ; }
     }            
 }
 
class  Publisher // 出版社
 {
     
public   delegate   void  PubComputerEventHandler( object  sender,PubEventArgs e); // 聲明事件所需的代理
      public   delegate   void  PubLifeEventHandler( object  sender,PubEventArgs e);
     
public   event  PubComputerEventHandler PubComputer; // 定議事件
      public   event  PubLifeEventHandler PubLife; // 定議事件
     
// 定議受保護的方法此方法主要是防止線程同步
      protected   virtual   void  OnPubComputer(PubEventArgs e)
     {
         PubComputerEventHandler handler
= PubComputer;
         
if (handler != null )
         {
             handler(
this ,e);
         }
     }
     
// 定議受保護的方法此方法主要是防止線程同步
      protected   virtual   void  OnPubLife(PubEventArgs e)
     {
         PubLifeEventHandler handler
= PubLife;
         
if (handler != null )
         {
             handler(
this ,e);
         }
     }
     
// 定議觸發事件的方法
      public   void  issueComputer( string  magazineName,DateTime pubDate) // 觸發事件的方法
     {
         Console.WriteLine(
" 發行 "   +  magazineName);
         OnPubComputer(
new  PubEventArgs(magazineName,pubDate));
     }
     
// 定議觸發事件的方法
      public   void  issueLife( string  magazineName,DateTime pubDate)
     {
         Console.WriteLine(
" 發行 "   +  magazineName);
         OnPubLife(
new  PubEventArgs(magazineName,pubDate));
     }
 }
 
class  Subscriber // 訂閱者
 {
     
private   string  _name;
     
public  Subscriber( string  name)
     {
         
this ._name = name;
     }
     
public   void  Receive( object  sender,PubEventArgs e) // 在事件訂閱者中定議事件處理程序
     {
 
         Console.WriteLine(e.pubDate 
+   "   "   +  _name  +   " 已經收到 "   +  e.magazineName);    
     }
 }
 
class  Story
 {
     
static   void  Main()
     {
         
// 事件發行者只會把事件發關給訂閱的用戶
         Publisher Pub = new  Publisher();
         Subscriber zs
= new  Subscriber( " 張三 " );
         Pub.PubComputer
+= new  Publisher.PubComputerEventHandler(zs.Receive); // 向事件發行者訂閱一個事件
         Subscriber ls = new  Subscriber( " 李四 " );
         Pub.PubComputer
+= new  Publisher.PubComputerEventHandler(ls.Receive);
         Pub.PubLife
+= new  Publisher.PubLifeEventHandler(ls.Receive);
         Pub.issueComputer(
" 電腦雜志 " ,Convert.ToDateTime( " 2006-1-1 " ));
         Pub.issueLife(
" 生活雜志 " ,Convert.ToDateTime( " 2006-1-1 " ));
         Console.WriteLine();
         Console.WriteLine(
" 一年以後李四不再訂閱<<電腦>>雜志 " );
         Pub.PubComputer
-= new  Publisher.PubComputerEventHandler(ls.Receive);
         Pub.issueComputer(
" 電腦雜志 " ,Convert.ToDateTime( " 2007-1-1 " ));
         Pub.issueLife(
" 生活雜志 " ,Convert.ToDateTime( " 2007-1-1 " ));        
     }
 }


/* 關於事件的說法:
 * 1,委托是一种自定的類型,委托定議了方法的類型.
 * 2,事件是委托的實例.使用委托實例的委托鏈注刪一些方法.
 * 使用+=註冊,-=撤銷
 * 3,當事件發生的時候,調用委托鏈中的這些方法.
 * 不妨稱這些方法為事件處理函數.
 * 
 * 下面的例子是
 * 熱水器發出水開的事件
 * 警報器接受這個事件,做出相應的動作.
 * 顯示器接受這個事件,做出相應該的動作.
 * 
 * 如果想讓報警器和顯示器能接受到這個事件,
 * 那麼方法需註冊這個事件.
 
*/
using  System;
using  Delegate;
// 熱水器
namespace  Delegate
{
    
public   class  Heater
    {
        
private   int  temperature = 0 ; // 聲明成員變量
         public   delegate   void  BoilHandler( int  param); // 聲明委托
         public   event  BoilHandler BoilEvent; // 聲明事件,委托的對像
         public   void  BoilWater() // 水的方法
        {
            
for ( int  i = 1 ;i <= 100 ;i ++ )
            {
                
this .temperature ++ ;
                
if ( this .temperature >= 99   &&  BoilEvent != null )
                {
                    BoilEvent(
this .temperature); // 調用所註冊的方法
                }
            }
        }
    }
    
// 警報器
     public   class  Alarm
    {
        
public   void  MakeAlert( int  param) // 參數也是就是簽名和委托的是一至的
        {
            Console.WriteLine(
" 水開了,度數為: "   +  param.ToString());
        }
    }
    
// 顯示器
     public   class  Display
    {
        
public   void  ShowMsg( int  param)
        {
            Console.WriteLine(
" 顯示當前度數為: "   +  param.ToString());
        }
    }
}
namespace  Athrun
{
    
class  Test
    {
        
static   void  Main()
        {
            Heater heater
= new  Heater();
            Alarm alarm
= new  Alarm();
            Display display
= new  Display();
            heater.BoilEvent
+= alarm.MakeAlert; // 註冊方法
            heater.BoilEvent += display.ShowMsg; // 註冊方法
            heater.BoilEvent -= display.ShowMsg; // 刪除方法
            heater.BoilWater(); // 溫度到達99時角發事件
        }
    }
}

你可能感兴趣的:(event)