程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#基礎原理拾遺——面試都愛問的委托和事件(糾正)

C#基礎原理拾遺——面試都愛問的委托和事件(糾正)

編輯:C#入門知識

      這篇博客是我昨天寫的,文中的觀點有些問題,後經過網友留言和個人學習發現錯誤,原文還是保留,更改補在後面,不怕贻笑大方,唯恐誤人子弟。不知道還能不能放在首頁,讓被誤導的同學再被反誤導一次。

一、原文

      幾乎所有的面試題都會問:事件是委托嗎,說說委托和事件的聯系和區別?每次答這個題都很蛋疼,因為把它們的關系說簡單了就描述不准確,想說清楚就不是一兩句話的事了。我通常在回答中加這麼一句:委托與事件的關系好比字段與屬性的關系。很多人理解它們的關系時也做這樣的類比,雖然簡單一句話概括了它們的關系,但總不能讓我感到滿意。

1、委托與事件到底什麼關系?

      當我們談委托與事件的關系時,是說委托這種類型和事件這種類型的關系呢,還是具體的委托對象和事件對象之間的關系?我以為是前者。那麼委托和事件是兩種類型,而字段和屬性是具體的對象,雖然都是封裝,我覺得兩者之間還是有區別的,事件對委托的封裝是在類級別的、抽象層次、穩定的封裝,而屬性對字段的封裝是在對象級別的、具體的、可自定義的封裝。由此造成的最直觀的區別就是,在發布者類中使用事件時,不需要提供對應的委托對象;而在類中使用屬性時,一般要提供對應的字段讓屬性來進行封裝。

      Reflector查看類之間的繼承關系如下:

                this.scroe = value; 
 (.GameOverDelegate !=                     
                     (value == .GameOverDelegate();

      以上Game2類中,委托對事件的模擬即是在對象級別做的封裝,AddMethod和RemoveMethod方法是在Game2類中實現的,而不是在OverDelegate委托中實現的,因此事件的模擬依賴了OverDelegate和Game2兩個類。而Game1中EventHandler類本身就封裝了委托,限制了其在外部(訂閱者)的實例化,這種功能的實現沒有依賴於Game1。所以事件的這種內部封裝機制減少了依賴,符合松耦合要求。

      以上是我個人的一點理解,有失偏頗之處還望批評指正。

      然而EventHandler內部是怎麼封裝的呢?我的思路尚不清晰,Reflector查看也沒看出個所以然,我自己會認真學習探索,在此也向各位請教,希望大家能告訴我答案或提供一些思路。為謝!

二、改正

3、其實不是EventHandler一人的功勞

      在上文中我以為事件對委托的封裝是EventHandler類一人的功勞,其實沒有深入理解的話很容易這麼想,因為在聲明事件的時候並沒有聲明對應的委托,直觀上就感覺這個封裝是發生在EventHandler類內部的。看了 @小AI 給我推薦的http://www.cnblogs.com/JimmyZhang/archive/2007/09/23/903360.html一文,發現問題所在。

      在Reflector中反編譯上面的例子,Game1類的結構如下:

      雖然這次出了錯,但並沒有使我灰心,相反,如果我不把自己的想法拿出來和大家交流,可能問題永遠得不到解決。唯一的弊端就是大膽的寫自己的想法,如果是錯誤的話,很可能誤導比我還菜的同學,我能做的就是盡量多方求證,並且出錯後及時改正。也勉勵和我一樣的菜鳥多寫博客,別怕暴漏錯誤,大家對於大牛中規中矩的blog已經看的boring了,小菜錯誤的想法裡可能偶爾就有著不被規則約束的創新。hehe

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved