C#基礎系列——再也不用擔心面試官問我“事件”了
前言:作為.Net攻城獅,你面試過程中是否遇到過這樣的問題呢:什麼是事件?事件和委託的區別?既然事件作為一種特殊的委託,那麼它的優勢如何體現?諸如此類...你是否也曾經被問到過?你又是否都答出來了呢?上兩篇由淺及深介紹了下委託的用法,這篇還是來說說事件。希望通過這篇的介紹,博友能有個系統的認識,至少應付面試沒問題了吧。不信?瞧瞧去~~
C#基礎系列目錄:
開篇博主也不多說廢話了,翠花,上答案。。。關於面試中涉及到的事件的問題,我們只需要抓住幾個關鍵點就好了:
(1)事件是委託的封裝,可以理解為一種特殊的委託。
(2)事件裡面其實就兩個方法(即add_event()和remove_event())和一個私有的委託變數,這兩個方法裡面分別是對這個私有的委託變數進行的合併和移除,當呼叫事件的+=時其實是呼叫的事件裡面的add_event()方法,同樣-=呼叫的是remove_event()方法。
(3)事件只能夠從物件外部增加新的響應方法和刪除已知的響應方法,而不能主動去觸發事件和獲取其他註冊的響應方法等資訊。如果使用公有的delegate則不能做這些限制,也就是說事件對委託做了限制,使委託使用起來更加方便。也有人說事件是對委託的閹割,大概也是這個意思。
如果回答的時候抓住了以上的3點,那麼我想你的面試應該不會太差。畢竟面試那麼短的時間,有一兩個亮點就很不錯了,你說呢。哪怕你對事件機制完全不懂,為了面試記住其中兩點也是很好的,工作經驗咱們沒有,換工作的經驗可不能沒有哦~~扯遠了,關於面試就到此為止。如果你還想繼續將事件瞭解透徹,彆著急,慢慢往下看。
1、事件的定義及由來:
定義事件:
public delegate void MyStudyEvent(object sender, EventArgs e); public class TestEvent { public event MyStudyEvent eMyStudyEvent; }
將這段程式碼生成dll後,通過反編譯工具reflector我們可以看到:
正如上文所說,可以看到當定義一個事件public event MyStudyEvent eMyStudyEvent的時候,編譯器會自動給他生成兩個方法add和remove,以及一個private的委託變數eMyStudyEvent。我們將反編譯程式碼copy出來看看。
//私有委託變數 private MyStudyEvent eMyStudyEvent; //add方法合併委託到eMyStudyEvent裡面 public void add_eMyStudyEvent(MyStudyEvent value) { MyStudyEvent event3; MyStudyEvent eMyStudyEvent = this.eMyStudyEvent; do { event3 = eMyStudyEvent; MyStudyEvent event4 = (MyStudyEvent)System.Delegate.Combine(event3, value); eMyStudyEvent = Interlocked.CompareExchange<MyStudyEvent>(ref this.eMyStudyEvent, event4, event3); } while (eMyStudyEvent != event3); } //remove方法移除eMyStudyEvent裡面已存在的委託 public void remove_eMyStudyEvent(MyStudyEvent value) { MyStudyEvent event3; MyStudyEvent eMyStudyEvent = this.eMyStudyEvent; do { event3 = eMyStudyEvent; MyStudyEvent event4 = (MyStudyEvent)System.Delegate.Remove(event3, value); eMyStudyEvent = Interlocked.CompareExchange<MyStudyEvent>(ref this.eMyStudyEvent, event4, event3); } while (eMyStudyEvent != event3); }
可以看到這兩個方法的主要作用就是在向private變數eMyStudyEvent裡面新增委託和移除委託。當呼叫事件的+=和-=時,eMyStudyEvent裡面就合併和移除傳過來的委託,當事件觸發的時候,eMyStudyEvent變數就執行。這樣設計也正好符合封裝的原則,保證了內部變數的安全性。
2、Framework裡面的事件:既然自定義的事件是這樣的,那麼有人就要問了,.Net裡面的事件是否也是如此。我們直接通過反編譯工具來看。我們找到System.Windows.Forms下面的Button類,這個也是我們Winform裡面使用最多的按鈕,我們來看看我們經常使用的事件。
base.DoubleClick轉到定義:
Events.AddHandler()轉到定義:
是不是很眼熟,也是通過Delegate.Combine()來合併委託。
3、自定義事件的使用。事件使用的例子園子裡面文章也很多,此片博主就以監聽資料夾裡面的1.txt檔案是否存在為例說明事件的使用以及使用事件和委託的區別。
首先定義事件以及觸發事件的方法:
public delegate void FileWatchEventHandler(object sender, EventArgs e); public class FileWatch { private bool _bLastStatus = false; public FileWatch() { } public event FileWatchEventHandler FileWatchEvent; protected virtual void OnFileChange(EventArgs e) { if (FileWatchEvent != null) { FileWatchEvent(this, e); } }
//事件監聽的方法 public void MonitorFile() { bool bCurrentStatus; while (true) { bCurrentStatus = File.Exists(@"C:\Users\user\Desktop\桌面資料夾\1.txt"); if (bCurrentStatus != _bLastStatus) { _bLastStatus = bCurrentStatus; OnFileChange(EventArgs.Empty); } Thread.Sleep(250); } } }
然後在Main函式裡面啟動監聽以及定義事件處理方法:
static FileWatch FileWatchEventSource; static void Main(string[] args) { FileWatchEventSource = new FileWatch(); //1. 啟動後臺執行緒新增監視事件 var thrd = new Thread(new ThreadStart(FileWatchEventSource.MonitorFile)); thrd.IsBackground = true; thrd.Start(); //2.註冊本地事件處理方法 FileWatchEventSource.FileWatchEvent += new FileWatchEventHandler(OnFileChange); Console.ReadLine(); } private static void OnFileChange(object Sender, EventArgs e) { Console.WriteLine(DateTime.Now.ToString() + ": 檔案發生改變."); }
啟動程式後,每當在資料夾裡面刪除和建立1.txt的時候就會列印提示檔案改變。
博主好奇心重,貌似這種監聽直接用委託也可以實現了。於是乎將event事件變數直接改成委託變數。
//public event FileWatchEventHandler FileWatchEvent; public FileWatchEventHandler FileWatchEvent;
然後執行。發現可以得到一樣的結果。
只是在反編譯的時候沒有add和remove方法而已:
這裡正是需要說明的上面的面試回答第三條:事件只能通過+=和-+去閹割委託,而不能主動觸發事件。如當使用事件的機制public event FileWatchEventHandler FileWatchEvent時。在Main函式裡面
static void Main(string[] args) { FileWatchEventSource = new FileWatch(); //1. 啟動後臺執行緒新增監視事件 var thrd = new Thread(new ThreadStart(FileWatchEventSource.MonitorFile)); thrd.IsBackground = true; thrd.Start(); //2.註冊本地事件處理方法 FileWatchEventSource.FileWatchEvent += new FileWatchEventHandler(OnFileChange); //這樣寫是報錯的。 FileWatchEventSource.FileWatchEvent(null, null); Console.ReadLine(); }
這樣寫是會報錯的FileWatchEventSource.FileWatchEvent(null, null);因為事件不能主動觸發,而改成委託後這樣寫就是正確的。並且如果是event變數,除了+=和-=操作,其他所有操作都會報錯:
從這裡可以看出,事件對委託進行了封裝和約束。
總而言之,言而總之,事件和委託,打一個不太恰當的比喻,就類似麵包和麵粉,麵包是由麵粉加工而來的,當我們肚子餓了的時候,麵包直接就能吃,麵粉還需要加工。而當我們需要麵條的時候,麵粉就派上用場了,麵包對於我們來說是用不了的。不知道這樣解釋好理解否。說了這麼多,確實有點繞,需要好好體會下。
相關推薦
C#基礎系列——再也不用擔心面試官問我“事件”了
前言:作為.Net攻城獅,你面試過程中是否遇到過這樣的問題呢:什麼是事件?事件和委託的區別?既然事件作為一種特殊的委託,那麼它的優勢如何體現?諸如此類...你是否也曾經被問到過?你又是否都答出來了呢?上兩篇由淺及深介紹了下委託的用法,這篇還是來說說事件。希望通過這篇的介紹,博友能有個系統的認識,至少應付面試沒
C#基礎系列:再也不用擔心面試官問我“事件”了
前言:作為.Net攻城獅,你面試過程中是否遇到過這樣的問題呢:什麼是事件?事件和委託的區別?既然事件作為一種特殊的委託,那麼它的優勢如何體現?諸如此類…你是否也曾經被問到過?你又是否都答出來了呢? 關於面試中涉及到的事件的問題,我們只需要抓住幾個關鍵點就好了: (1
再也不用擔心面試官問你HashCode和equals了
結論 如果兩個物件相等,則hashcode()必須相等。 如果兩個物件相等,a.equals(b)==b.equals(a)==true 如果兩個物件有相同的hashcode值,他們也不一定是相等的。但若兩個物件相等,則hashCode值一定相等。 因此若equals()被覆
看完這篇,再也不怕面試官問我執行緒池了
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20201129220549759.png) ## 一、為什麼需要執行緒池 在實際使用中,執行緒是很佔用系統資源的,如果對執行緒管理不完善的話很容易導致系統問題。因此,在大多數併發框架中都會使用執行緒池來管理執行緒,使用執行緒
面試官問我如何用python製作一個AlphaGo,我把演算法寫的明明白白
小史是一個應屆生,雖然學的是電子專業,但是自己業餘時間看了很多網際網路與程式設計方面的書,一心想進BAT網際網路公司。 當然在學習Python的道路上肯定會困難,沒有好的學習資料,怎麼去學習呢? 學習Python中有不明白推薦加入交流群 &
假如面試官問我打算在該公司做多久?願意籤幾年合同?為什麼?我應該怎麼回答好呢?急急急,謝謝回答
如果你認為這個公司還可以,你就直接對她說打算長期幹下去,(先上網查查這個公司的概況,之後在你充分的瞭解了這個公司的情況之下,你才能這樣回答)就像上邊的回答的那樣,有時候公司是缺人才的,但他們又不明說,這就要看你自己的態度了,願意幹就多誇幾句這個公司,不知你有多大但不管有多大
面試官問我,使用Dubbo有沒有遇到一些坑?我笑了。
開發十年,就只剩下這套架構體系了! >>>
面試官問我,Redis分散式鎖如何續期?懵了。
開發十年,就只剩下這套架構體系了! >>>
面試官問我“Java中的鎖有哪些?以及區別”,我跪了
讀寫鎖 queue get 吞吐量 參考 示例 事情 自動 高並發 在讀很多並發文章中,會提及各種各樣鎖如公平鎖,樂觀鎖等等,這篇文章介紹各種鎖的分類。介紹的內容如下: 公平鎖/非公平鎖 可重入鎖 獨享鎖/共享鎖 互斥鎖/讀寫鎖 樂觀鎖/悲觀鎖 分段鎖 偏
面試官問我:平常如何對你的Java程式進行調優?
作者:張俊城, 郭理勇, 劉建 來源:http://t.cn/AiCTERJz Java 應用效能優化是一個老生常談的話題
騰訊面試官問我Java中boolean型別佔用多少個位元組?我說一個,面試官讓我回家等通知
本文首發於微信公眾號:程式設計師喬戈裡 什麼是boolean型別,根據官方文件的描述: boolean: The boolean data type has only two possible values: true and false. Use this data type
美團面試官問我一個字元的String.length()是多少,我說是1,面試官說你回去好好學一下吧
本文首發於微信公眾號:程式設計師喬戈裡 public class testT { public static void main(String [] args){ String A = "hi你是喬戈裡"; System.out.printl
當阿里面試官問我:Java建立執行緒有幾種方式?我就知道問題沒那麼簡單
這是最新的大廠面試系列,還原真實場景,提煉出知識點分享給大家。 點贊再看,養成習慣~ 微信搜尋【武哥聊程式設計】,關注這個 Java 菜鳥。 昨天有個小夥伴去阿里面試實習生崗位,面試官問他了一個老生常談的問題:你說一說 Java 建立執行緒都有哪些方式? 這哥們心中竊喜,這個老生常談的問題早已背的滾瓜爛熟
【Java8新特性】面試官問我:Java8中建立Stream流有哪幾種方式?
## 寫在前面 > 先說點題外話:不少讀者工作幾年後,仍然在使用Java7之前版本的方法,對於Java8版本的新特性,甚至是Java7的新特性幾乎沒有接觸過。真心想對這些讀者說:你真的需要了解下Java8甚至以後版本的新特性了。 ># > 今天,一名讀者出去面試,面試官問他:說說Java8
阿里P7崗位面試,面試官問我:為什麼HashMap底層樹化標準的元素個數是8
前言 先宣告一下,本文有點標題黨了,像我這樣的菜雞何德何能去面試阿里的P7崗啊,不過,這確實是阿里p7級崗位的面試題,當然,參加面試的人不是我,而是我部門的一個大佬。他把自己的面試經驗分享給了我,也讓我間接體會下阿里級別的面試難度,這樣算起來,我也勉強算是經歷面試過阿里P7的崗位的人吧,頓時感覺信心暴漲。
【高併發】面試官問我如何使用Nginx實現限流,我如此回答輕鬆拿到了Offer!
## 寫在前面 > 最近,有不少讀者說看了我的文章後,學到了很多知識,其實我本人聽到後是非常開心的,自己寫的東西能夠為大家帶來幫助,確實是一件值得高興的事情。最近,也有不少小夥伴,看了我的文章後,順利拿到了大廠Offer,也有不少小夥伴一直在刷我的文章,提升自己的內功,最終成為自己公司的核心業務開發人
【Nginx】面試官問我Nginx能不能配置WebSocket?我給他現場演示了一番!!
## 寫在前面 > 當今網際網路領域,不管是APP還是H5,不管是微信端還是小程式,只要是一款像樣點的產品,為了增加使用者的互動感和使用者粘度,多多少少都會涉及到聊天功能。而對於Web端與H5來說,實現聊天最簡單的就是使用WebSocket了。而在實現WebSocket聊天的過程中,後臺也往往會部署多
當面試官問我ArrayList和LinkedList哪個更佔空間時,我這麼答讓他眼前一亮
前言 今天介紹一下Java的兩個集合類,ArrayList和LinkedList,這兩個集合的知識點幾乎可以說面試必問的。 對於這兩個集合類,相信大家都不陌生,ArrayList可以說是日常開發中用的最多的工具類了,也是面試中幾乎必問的,LinkedList可能用的少點,但大多數的面試也會有所涉及,尤其是關於
笑了,面試官問我知不知道非同步程式設計的Future。
荒腔走板 大家好,我是 why,歡迎來到我連續周更優質原創文章的第 60 篇。 老規矩,先來一個簡短的荒腔走板,給冰冷的技術文注入一絲色彩。 上面這圖是我五年前,在學校宿舍拍的。 前幾天由於有點事情,打開了多年沒有開啟的 QQ。然後突然推送了一個“那年今日”傳送的動態。 這張圖片就是那個動態裡面的。 20
30 張圖解 | 高頻面試知識點總結:面試官問我高併發服務模型哪家強?
文章每週持續更新,原創不易,「三連」讓更多人看到是對我最大的肯定。可以微信搜尋公眾號「 後端技術學堂 」第一時間閱讀(一般比部落格早更新一到兩篇) 面試中經常會被問到高效能服務模型選擇對比,以及如何提高服務效能和處理能力,這其中涉及作業系統軟體和計算機硬體知識,其實都是在考察面試者的基礎知識掌握程度,但如