C#事件的使用(一)

來源:互聯網
上載者:User

==============
@ 在類中定義事件
==============

using System;

// Mail 管理。
class MailManager{
    // 1.定義事件參數,用於向事件接受者傳遞附加資訊。
    // 事件參數類都應該繼承自 System.EventArgs,並且類型名稱以 EventArgs 結束。
    public class MailMsgEventArgs : EventArgs{    
        public MailMsgEventArgs(string from, string to, string subject, string body) {
            this.from = from;         // 寄件者。
            this.to = to;                // 接受者。
            this.subject = subject; // 主題。
            this.body = body;       // 本文。
        }
        public readonly string from, to, subject, body;
    } 

    // 2.定義一個委託類型,用於指定事件觸發時被調用的方法原型。
    // 委託類型的名稱應該以 EventHandler 結束。另外方法原型傳回值應該為 void,並且有兩個參數:
    // 第一個參數指向發送通知的對象,第二個是事件參數。如果我們定義的時間沒有需要傳遞給事件接受者
    // 的附加資訊,就不需要定義新的委託類型,直接使用 System.EventHandler,並將 EventArgs.Empty
    // 傳遞給第二個參數即可。
    public delegate void MailMsgEventHandler(Object sender, MailMsgEventArgs args);

    // 3.定義事件。
    // 如下定義的事件的名稱是 MailMsg,類型為 MailMsgEventHandler,其含義為所有事件接受者都必須提供
    // 一個原型和 MailMsgEventHandler 想匹配的方法。
    public event MailMsgEventHandler MailMsg;

    // 4. 觸發事件。將一些外部輸入轉化為觸發事件的動作。
    public void SimulateArrivingMsg(string from, string to, string subject, string body) {
        MailMsgEventArgs e = new MailMsgEventArgs(from, to, subject, body);
        
        // 調用虛方法通知對象事件已發生,如果衍生類別型沒有重寫該虛方法,
        // 對象將通知所有登記的時間偵聽者。
        OnMailMsg(e);
    }

    // 5.事件處理,負責通知事件的偵聽者。
    protected virtual void OnMailMsg(MailMsgEventArgs e) {
        if (MailMsg != null) {
            // 將事件通知給委託鏈表上的所有對象。
            MailMsg(this, e);
        }
    }
}

 

======================
@ 編譯器對事件定義語句的處理
======================

對於上面代碼中的定義事件的語句:
public event MailMsgEventHandler MailMsg;
編譯器會將其翻譯為如下三個方法:

// 1. 一個初始化為 null 的"私人"委託類型欄位。
private MailMsgEventHandler MailMsg = null;
// 2. 一個允許其他對象登記事件的"公有" add_* 方法。
[MethodImplAttribute(MethodImplOptions.Synchronized)]
public void add_MailMsg(MailMsgEventHandler handler){
 this.MailMsg = (MailMsgEventHandler)Delegate.Combine(MailMsg, handler);
}
// 3. 一個允許其他對象登出事件的"公有" remove_* 方法。
[MethodImplAttribute(MethodImplOptions.Sysnchronized)]
public void remove_MailMsg(MailMsgEventHandler handler){
 MailMsg = (MailMsgEventHandler).Delegate.Remove(MailMsg, handler);
}

 

add_* 和 remove_* 方法都應用了一個 MethodImplAttribute 特性,這些方法被標識為同步方法,使得它們得以
實現安全執行緒:也就是多個事件偵聽者可以同時登記或者登出事件,而不損壞委託鏈表。這兩個方法的訪問限制
取決於事件的訪問限制,如果事件被定義為受保護事件,那麼這兩個方法也將為受保護方法。

============
@ 定義偵聽事件的類
============

// 傳真機偵聽 MailManager 的 MailMsg 事件,並發送傳真(輸出到控制台)。
class Fax
{
    // 將 MailManager 對象傳遞給建構函式。
    public Fax(MailManager mm) {
        // 構造一個指向 FaxMsg 回調方法的 MailMsgEventHandler 委託執行個體,
        // 然後登記 MailManager 的 MailMsg 事件。
        mm.MailMsg += new MailManager.MailMsgEventHandler(FaxMsg);
    }

    // MailManager 將調用該方法來通知 Fax 對象收到到一個新的電子郵件訊息。
    // sender: 表示 MailManager 對象,如果希望和事件的觸發者通訊,可以使用該參數。
    // e:表示 MailManager 對象提供的一些附加事件資訊。
    private void FaxMsg(Object sender, MailManager.MailMsgEventArgs e) {
        Console.WriteLine(" From: {0} \n To: {1} \n Subject: {2} \n Body: {3} \n" + 
            e.from, e.to, e.subject, e.body);
    }

    // 登出事件。
    public void Unregister(MailManager mm) {
        // 建立一個新的委託執行個體是為了將其從委託鏈表中移除(參見《深入理解委託》)
        MailManager.MailMsgEventHandler callback = new MailManager.MailMsgEventHandler(FaxMsg);
        mm.MailMsg -= callback;
    }
}

 

========
@ 使用事件
========

using System;

public class Test
{
    public static void Main(string[] args) {
        // 定義事件寄件者 mm。
        MailManager mm = new MailManager();
        
        // 定義事件偵聽者,偵聽 mm 發送的時間。
        Fax fax = new Fax(mm);

        // 觸發事件寄件者定義的事件。
        mm.SimulateArrivingMsg("Me", "You", "Love", "I love you !"); 
    }
}

輸出:
 From: Me
 To: You
 Subject: Love
 Body: I love you !

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.