C# 委托和事件(一):最簡單的委托和事件

来源:http://www.cnblogs.com/kingsanity/archive/2016/12/11/6158772.html
-Advertisement-
Play Games

C#的事件基於委托,所以先說委托。 一切脫離實際場景的抽象概念新手看上去就像是在扯犢子,不錯,我就是個新手。所以我需要一個實際的場景。 明天剛好考試(商務英語),考試上有兩個角色(class):老師(Teacher)和學生(Student),在考試時間終止的時候,老師會觸發(invoke)一個事件( ...


 

C#的事件基於委托,所以先說委托。

一切脫離實際場景的抽象概念新手看上去就像是在扯犢子,不錯,我就是個新手。所以我需要一個實際的場景。

明天剛好考試(商務英語),考試上有兩個角色(class):老師(Teacher)和學生(Student),在考試時間終止的時候,老師會觸發(invoke)一個事件(event):“考試時間到了,我tm要收卷子了!”(OnTestTimeUp),而每個學生都要訂閱這個事件,併在這個事件發生的時候上交試卷(HandInTestPaper)。如果不用事件的話,老師在時間結束的時候就要調用每個學生的的HandInTestPaper方法,如果使用事件,只要在學生被實例化的時候在事件上增加一個訂閱即可。

1、老師和學生之間的橋梁

老師和學生之間的橋梁用委托來完成,這裡就用最簡單的一種委托:沒有返回、沒有參數、不支持泛型:

public delegate void TestTimeUpHandler();

接著,用這個委托定義一個事件,這樣學生就可以訂閱這個事件

public event TestTimeUpHandler TestTimeUp;

學生訂閱事件後,當老師觸發這個事件的時候,學生就會做出一些響應

public void OnTestTimeUp()
{
    TestTimeUp?.Invoke();
}

2、學生如何訂閱?

首先回到剛纔的委托,這個委托非常簡單,沒有返回、沒有參數,所以學生類中只要有一個方法,簽名與這個一致就可以訂閱這個事件:

public void HandInTestPaper()
{
    Console.WriteLine("The test paper has been handed in.");  
}

然後在實例化後直接將這個方法訂閱給事件即可

3、兩邊的關係

4、完整的例子

Delegate

    /// <summary>
    /// 委托,考試時間到的Handler
    /// </summary>
    public delegate void TestTimeUpHander();

Teacher

    /// <summary>
    /// 教師類
    /// </summary>
    public class Teacher
    {
        public event TestTimeUpHander TestTimeUp;

        public void OnTestTimeUp()
        {
            TestTimeUp?.Invoke();
        }
    }

Student

    /// <summary>
    /// 學生類
    /// </summary>
    public class Student
    {
        public string Name { get; private set; }

        public Student(string name)
        {
            this.Name = name;
        }

        public void HandInTestPaper()
        {
            Console.WriteLine($"{this.Name}\' paper has been handed in");
        }
    }

5、具體場景實現

    public class Program
    {
        public static void Main()
        {
            Teacher teacher = new Teacher();
            var tom = new Student("Tom");
            var jerry = new Student("Jerry");
            var spark = new Student("Spark");
            var tyke = new Student("Tyke");

            // 訂閱teacher的TestTimeUp事件
            teacher.TestTimeUp += tom.HandInTestPaper;
            teacher.TestTimeUp += jerry.HandInTestPaper;

            // invoke TestTimeUp 事件
            teacher.OnTestTimeUp();

            Console.WriteLine();

            teacher.TestTimeUp -= tom.HandInTestPaper;
            teacher.TestTimeUp += tyke.HandInTestPaper;

       teacher.OnTestTimeUp(); Console.ReadKey(); } }

運行的結果如下:

可以看到,第一次觸發事件的時候,只有Tom和Jerry兩個訂閱了事件的實例執行了HandInTestPaper方法,第二次觸發事件前,移除了Tom的訂閱,同時增加了Tyke的訂閱,所以Jerry和Tyke執行了HandInTestPaper方法。

以上,是最簡單的C#委托與事件的實現,複雜的方法日後再說

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 問題描述:在Windows10下安裝Ubuntu。 使用工具:Windows10、Ubuntu16.04 LTS安裝包、UltraISO、easyBCD。 操作步驟: 1、安裝之前要給Ubuntu分出一定大小的磁碟空間。我用170G來安裝Ubuntu。我的硬碟比較大,如果硬碟較小,可以選擇50G等大 ...
  • 問題概述:在裝系統的時候有時候並不能一下分出完全符合我們使用習慣的分區大小,我們可能需要在後期調整分區大小。以下是有關分區大小調整的操作。 使用工具:Windows磁碟管理工具。 操作步驟: 1、使用組合鍵win+x,彈出菜單,選中“電腦管理”,選擇“磁碟管理”。 2、這裡簡要說明一下Window ...
  • 問題概述:因為在自己學習Linux的時候,按照網上的教程錯誤的刪除了Ubuntu的一個內核驅動,導致Ubuntu不能啟動。我想到的辦法是重新安裝系統,重裝系統的第一步便是將Ubuntu從電腦中卸載。該筆記是有關如何刪除Ubuntu啟動項的。 使用工具:Windows10,Ubuntu16.04 LT ...
  • NAND FLASH是一個存儲晶元 那麼: 這樣的操作很合理"讀地址A的數據,把數據B寫到地址A" 問1. 原理圖上NAND FLASH和S3C2440之間只有數據線, 怎麼傳輸地址? 答1.在DATA0~DATA7上既傳輸數據,又傳輸地址 當ALE為高電平時傳輸的是地址, ... ...
  • Linux設備模型是對系統設備組織架構進行抽象的一個數據結構,旨在為設備驅動進行分層、分類、組織。降低設備多樣性帶來的Linux驅動開發的複雜度,以及設備熱拔插處理、電源管理等。 ...
  • 之前沒怎麼註意,在使用下載盒通過isp下載stm32時,由於是通過stm32板子給下載盒供電,所以是我的stm32板子和下載盒同時上電。這樣總是不能夠進入下載模式,後來對下載盒進行模擬,發現在下載發送了7F之前,下載盒已經收到了一個位元組,導致在判斷首位元組時出錯。 後來就先把下載和給去了,直接把串口接 ...
  • 在2.1、欄目的前臺顯示中因右鍵沒有添加視圖把微軟給鄙視了一下,後來有仔細研究了一下發現應該鄙視自己,其實這個功能是有的,是自己沒搞清楚亂吐糟。 其實只要在NuGet中安裝兩個包(Microsoft.VisualStudio.Web.CodeGeneration.Tools和Microsoft.Vi... ...
  • 前面一篇里提到事件是通過委托來進行關聯的,而委托是可以帶各種各樣的參數的,其中就可以用事件參數(EventArgs),同時,也可以用.Net框架裡邊提供的一個委托EventHandler來Handle事件。 一樣,搞一個場景(這個場景是書里的):買車。經銷商(CarDealer)會上新車(NewCa ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...