本文討論類型中定義的最后一種成員:事件
定義了時間成員的類型允許類型通知其他對象發生了特定的事情。
具體的說,定義了時間成員的類型能提供以下功能:
CLR事件模型以委托為基礎。委托是調用回調方法的一種類型安全的方式。
本文我們將通過一個小栗子來學習一下事件怎么使用:
假定有個bolg平臺可以訂閱文章,用戶A、B、C可以通過訂閱或取消訂閱來接收或者不接受此平臺的文章。即,我是管理員,我在blog上發了一篇文章,那么訂閱blog的用戶就可以收到這篇文章了。
下面我們來實現這個功能,順便來學習下事件的使用:
約定:這種類型應該從System.EventArgs派生,而且類名以EventArgs結束。
internal class BlogEventArgs : EventArgs{    PRivate readonly String author, content;    private DateTime tdate;    public BlogEventArgs(string author,string content,DateTime date)    {        this.author = author;        this.content = content;        this.tdate = date;    }    public string Author { get { return author;} }    public string Content { get { return content; } }    public DateTime TDate { get { return tdate;} }}約定:事件使用event關鍵字。每個事件成員要指定以下內容:可訪問性標識符;委托類型;以及名稱。
internal class BlogManager{    public event EventHandler<BlogEventArgs> NewBlog;}約定:類要定義一個受保護的虛方法。引發事件時,類及其派生類中的代碼回調用該方法。方法只接受一個參數,即BlogEventArgs對象
protected virtual void OnNewBlog(BlogEventArgs e)    {        EventHandler<BlogEventArgs> temp = Volatile.Read(ref NewBlog);        if (temp!=null)        {            temp(this, e);        }    }關于為什么要像上邊這樣寫,只能說這樣是線程安全的方式引發事件,其他方式可能會有線程方面的問題。
在BlogManager中,調用WriteNewBlog來指出寫了一篇新博客
public void WriteNewBlog(string author, string content, DateTime date)    {        BlogEventArgs e = new BlogEventArgs(author,content,date);        OnNewBlog(e);    }比如User類型想訂閱或取消這個博客
internal sealed class Reader{    public Reader(BlogManager blogManager)    {        blogManager.NewBlog += blogManager_NewBlog;    }    void blogManager_NewBlog(object sender, BlogEventArgs e)    {        Console.WriteLine("讀者已收到博客!");        Console.WriteLine("作者:{0},內容:{1},發表時間:{2}",e.Author,e.Content,e.TDate.ToShortTimeString());    }    public void Unregister(BlogManager bmManager)    {        bmManager.NewBlog -= blogManager_NewBlog;    }}class Program{    static void Main(string[] args)    {        BlogManager bmManager = new BlogManager();        Reader readerA  =new Reader(bmManager);        bmManager.WriteNewBlog("1號作者", "這是我的第一篇文章", DateTime.Now);        readerA.Unregister(bmManager);        bmManager.WriteNewBlog("1號作者", "這是我的第二篇文章,應該收不到", DateTime.Now);        Console.ReadKey();    }}
根據書本《CLR via C#》的小栗子自己更改了一點,希望對你有幫助。
新聞熱點
疑難解答