本文討論類型中定義的最后一種成員:事件
定義了時間成員的類型允許類型通知其他對象發生了特定的事情。
具體的說,定義了時間成員的類型能提供以下功能:
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#》的小栗子自己更改了一點,希望對你有幫助。
新聞熱點
疑難解答