2015年12月15日 星期二

宣告事件二

如果每個事件的儲存開銷太大,我們可以在類別中包含事件存取宣告,按私有成員的規則存放事件控制碼列表。如下:
 
修飾子 event 型別識別字 {add { } ; remove { } ; }

上面的事件格式宣告,具有add , remove存取子,就像屬性宣告中的get ,set存取子一樣。
事件存取子的例子:
using System;
using System.Diagnostics;
namespace Event_test
{
   //宣告一個delegate
  public delegate void EventHandler( );
  public class MyClass
  {
     //宣告一個成員變數來保存事件控制碼 (事件被觸發時被叫用的delegate)
     private EventHandler m_Handler = null ;
    //觸發事件
  public void FireMyEvent( )
    {
      if (m_Handler != null )
       {
          m_Handler ( ) ;
        }
     }

     //宣告事件存取子帶入委派所宣告的型別
  public event EventHandler MyEvent  
    {
       add  //新增存取子
       {
          //注意,存取子中實際包含了一個名為value的隱含參數
   //該參數的值即為客戶程式叫用 += 時傳遞過來的delegate
         Console.WriteLine ("MyEvent add被叫用,value的HashCode為:" +
         value.GetHashCode( ) );
        //設置 m_Handler 域保持新的handler
         if (value != null ) { m_Handler = value ; } ;
        }
        //刪除存取子
  remove
       {
            Console.WriteLine ("MyEvent  remove被叫用,value的HashCode為:" +
         value.GetHashCode( ) );
         //設置m_Handler為null,該事件不再被觸發
  if ( value == m_Handler) { m_Handler = null ; }
     }
   }
 }
public calss Program
{
  //真正的事件處理函數
 puiblic static void MyEventHandler( )
   {
      Console.WriteLine (" 這是一個事件被執行 ! ") ;
    }

public static void Main( )
  {
     MyClass my = new MyClass ( ) ;
     //基於MyEventHandler 函數定義一個EventHandler
 EventHandler MyHandler = new EventHandler(MyEventHandler );
 
 Console.WriteLine (" MyHandler of HashCode is: " + MyHandler.GetHashCode ( ) ) ;
 Console.WriteLine ("----------------------------------------------------------------------------------") ;

  //預訂事件
  Console.WriteLine ("my.MyEvent += MyHandler 被叫用 ") ;
  my.MyEvent += MyHandler ;

   //觸發事件
   Console.WriteLine ("Main 函數觸發 my 的 MyEvent 事件 ") ; 
 my.FireMyEvent ( ) ;

   //撤銷事件
   Console.WriteLine ("my.MyEvent -= MyHandler 被叫用 ") ;
   my.MyEvent -= MyHandler ;
   Console.WriteLine ("----------------------------------------------------------------------------------") ;
  //再次試圖觸發事件
   Console.WriteLine ("Main 函數試圖在撤銷事件後觸發 my 的 MyEvent 事件 ") ; 
  my.FireMyEvent ( ) ;

所以我們可以知道,當 Main 函數叫用my.FireMyEvent ( )時,my的m_Handler被叫用,也就是我們的MyEventHandler被叫用,所以會輸出 " 這是一個事件被執行 ! "。

沒有留言:

張貼留言