1. 程式人生 > >C#基礎系列——再也不用擔心面試官問我“事件”了

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 張圖解 | 高頻面試知識點總結:面試高併發服務模型哪家強?

文章每週持續更新,原創不易,「三連」讓更多人看到是對我最大的肯定。可以微信搜尋公眾號「 後端技術學堂 」第一時間閱讀(一般比部落格早更新一到兩篇) 面試中經常會被問到高效能服務模型選擇對比,以及如何提高服務效能和處理能力,這其中涉及作業系統軟體和計算機硬體知識,其實都是在考察面試者的基礎知識掌握程度,但如