[.NET] C# 知識回顧 - Event 事件

来源:http://www.cnblogs.com/liqingwen/archive/2016/11/15/6060297.html
-Advertisement-
Play Games

C# 知識回顧 - Event 事件 段子:內容與主題無關 很多年輕人會問到:看什麼書好呢?這是比較專業的回答: 第一階段:《數據結構》,《軟體工程》,《C語言》,《C++》,《Java》,《設計模式》。。。第二階段:《莫生氣》,《佛經》,《老子》,《思想政治》,《論持久戰》第三階段:《頸椎病康復指 ...


C# 知識回顧 - Event 事件

【博主】反骨仔    【原文】http://www.cnblogs.com/liqingwen/p/6060297.html  

========== 段子:內容與主題無關 ==========

很多年輕人會問到:看什麼書好呢?這是比較專業的回答:

第一階段:《數據結構》《軟體工程》《C語言》《C++》《Java》《設計模式》。。。
第二階段:《莫生氣》《佛經》《老子》《思想政治》,《論持久戰》
第三階段:《頸椎病康復指南》,《腰間盤突出日常護理》,《心臟病的預防與防治》,《高血壓降壓寶典》,《強迫症的自我恢復》
第四階段:《迷戀》,《謝謝你折磨我》,《自私與貪婪》,《走向奴役之路》
第五階段:《活著》

========== 段子:內容與主題無關 ==========


 

  昨天,通過《C# 知識回顧 - 事件入門》介紹了事件的定義及簡單用法,今天我們通過控制台來看下“發佈 - 訂閱”的基本用法。

 

目錄

 

一、發佈符合 .NET 準則的事件

  下麵的過程演示瞭如何將符合標準 .NET 模式的事件添加到您的類和結構中。  .NET類庫中的所有事件均基於 EventHandler 委托,定義如下:  

public delegate void EventHandler(object sender, EventArgs e);

  你可以嘗試手動輸入 EventHandler ,然後按下“F12”跳轉到定義:

 

  .NET Framework 2.0 引入了此委托的一個泛型版本,即 EventHandler<TEventArgs>

  【備註】雖然您定義的類中的事件可基於任何有效委托類型(甚至是可返回值的委托),但是,通常建議您使用 EventHandler 讓事件基於 .NET 模式,如下麵的示例所示。

 

二、採用 EventHandler 模式發佈事件

  1.(如果不需要與事件一起發送自定義數據,請跳過此步驟,進入步驟 3a。)在發行者類和訂閱方類均可看見的範圍中聲明自定義數據的類。  然後添加保留您的自定義事件數據所需的成員。  在此示例中,會返回一個簡單字元串。

1     class MyEventArgs : EventArgs
2     {
3         public string Message { get; private set; }
4 
5         public MyEventArgs(string message)
6         {
7             Message = message;
8         }
9     }

 

  2.(如果您使用的是 EventHandler<TEventArgs> 的泛型版本,請跳過此步驟。)在發佈類中聲明一個委托。  為它指定以 EventHandler 結尾的名稱。  第二個參數指定自定義 EventArgs 類型。 

    delegate void MyEventHandler(object sender, MyEventArgs args);

 

  3.使用以下任一步驟,在發佈類中聲明事件。

    (1)如果沒有自定義 EventArgs 類,事件類型就是非泛型 EventHandler 委托。無需聲明委托,因為它已在創建 C# 項目時包含的 System 命名空間中進行了聲明。將以下代碼添加到發行者類中。 

public event EventHandler MyEvent;

 

    (2)如果使用的是 EventHandler 的非泛型版本,並且您有一個由 EventArgs 派生的自定義類,請在發佈類中聲明您的事件,並且將來自步驟 2 的委托用作類型。

public event MyEventHandler MyEvent;

 

    (3)如果使用的是泛型版本,則不需要自定義委托。  相反,在發行者類中,您應將事件類型指定為 EventHandler<MyEventArgs>,將尖括弧中的內容替換為自己的類的名稱。  

public event EventHandler<MyEventArgs> MyEvent;

 

三、一個簡單的發佈訂閱 Demo

  下麵的示例通過將自定義的 MyEventArgs 類和 EventHandler<TEventArgs> 進行演示:

This is MyEventArgs.cs
 1     /// <summary>
 2     /// 事件參數
 3     /// </summary>
 4     /// <remarks>一個自定義的類:自定義事件的參數</remarks>
 5     class MyEventArgs : EventArgs
 6     {
 7         public string Message { get; }
 8 
 9         public MyEventArgs(string message)
10         {
11             Message = message;
12         }
13     }

 

This is Publisher.cs
 1     /// <summary>
 2     /// 事件發佈者
 3     /// </summary>
 4     class Publisher
 5     {
 6         //聲明一個泛型事件
 7         public event EventHandler<MyEventArgs> MyEvent;
 8 
 9         public void Publish()
10         {
11             Console.WriteLine("Publis is starting");
12 
13             //你可以在事件觸發前寫些代碼
14 
15             OnMyEvent(new MyEventArgs(DateTime.Now.ToString()));
16         }
17 
18         /// <summary>
19         /// 觸發事件
20         /// </summary>
21         /// <param name="args"></param>
22         /// <remarks>虛方法,允許子類重寫調用行為</remarks>
23         protected virtual void OnMyEvent(MyEventArgs args)
24         {
25             //只有在事件訂閱時(!= null),才觸發事件
26             MyEvent?.Invoke(this, args);
27         }
28     }

 

This is Subscriber.cs
 1     /// <summary>
 2     /// 訂閱者
 3     /// </summary>
 4     class Subscriber
 5     {
 6         public Guid Guid { get; }
 7 
 8         public Subscriber(Publisher publisher)
 9         {
10             Guid = Guid.NewGuid();
11             //使用 C# 2 的語法進行訂閱
12             publisher.MyEvent += Publisher_MyEvent;
13         }
14 
15         /// <summary>
16         /// 事件處理程式
17         /// </summary>
18         /// <param name="sender"></param>
19         /// <param name="args"></param>
20         private void Publisher_MyEvent(object sender, MyEventArgs args)
21         {
22             Console.WriteLine($"    Message is {args.Message}, Guid is {Guid}.");
23         }
24     }

 

This is Program.cs   //用於啟動
 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             var publisher = new Publisher();
 6             var subscriber1 = new Subscriber(publisher);
 7             var subscriber2 = new Subscriber(publisher);
 8 
 9             //觸發事件
10             publisher.Publish();
11 
12             Console.WriteLine("OK!");
13             Console.Read();
14         }
15     }

 

 

四、實現自定義事件訪問器

  事件是特殊類型的多路廣播委托,只能從聲明它的類中調用。客戶端代碼通過提供對應在引發事件時調用的方法的引用來訂閱事件。這些方法通過事件訪問器添加到委托的調用列表中,事件訪問器類似於屬性訪問器,不同之處在於事件訪問器被命名為 add 和 remove在大多數情況下都不需要提供自定義的事件訪問器。如果您在代碼中沒有提供自定義的事件訪問器,編譯器會自動添加事件訪問器。但在某些情況下,您可能需要提供自定義行為。示例如下:

 1     class MyClass
 2     {
 3         /// <summary>
 4         /// 5         /// </summary>
 6         private static object Locker = new object();
 7 
 8         /// <summary>
 9         /// 介面
10         /// </summary>
11         public interface IMyEvent
12         {
13             event EventHandler OnCall;
14         }
15 
16         public class MyEvent : IMyEvent
17         {
18             /// <summary>
19             /// 觸發前事件
20             /// </summary>
21             event EventHandler PreEvent;
22 
23             public event EventHandler OnCall
24             {
25                 add
26                 {
27                     lock (Locker)
28                     {
29                         PreEvent += value;
30                     }
31                 }
32                 remove
33                 {
34                     lock (Locker)
35                     {
36                         PreEvent += value;
37                     }
38                 }
39             }
40         }
41     }

 

傳送門

  《C# 知識回顧 - 序列化

  《C# 知識回顧 - 表達式樹 Expression Trees

  《C# 知識回顧 - 特性 Attribute》、《剖析 AssemblyInfo.cs - 瞭解常用的特性 Attribute

  《C# 知識回顧 - 委托 delegate》、《C# 知識回顧 - 委托 delegate (續)

  《C# 知識回顧 - 事件入門

 


【參考】微軟官方文檔


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

-Advertisement-
Play Games
更多相關文章
  • 當我們用socket進行編程的時候,細節上都是選擇一個 ,`AF_INET`再根據相應的類型填充地址,其實根據通信需求,有幾種簡單的服務模型可供選用,掌握了這些框架再結合socket高度的抽象,可以為我們編寫簡單的伺服器程式提供指導 迴圈服務 用戶請求服務需要排隊,伺服器一次只能服務一個客戶,服務完 ...
  • 一、開篇立論= =.. 上次說到博主在電腦上搭建了代理伺服器來繞過天翼客戶端的共用限制,然而經過實際測試還不夠完美,所以本著生命不息,折騰不止的精神,我又開始研究搭建vpn伺服器= =... (上次的博文:win10搭建代理伺服器實現繞過校園網的共用限制--從入門到放棄) 不得不說,這是一個痛苦的過 ...
  • line 13: [ 0: unary operator expected please use "sudo service tomcat stop|start|restart" 出現此錯誤,需要去編輯/etc/init/tomcat 然後把 U_UID= 改成 U_UID=0 就可以了 ...
  • 首先需要知道的是命令提示符 [root@localhost ~] # 當前登錄用戶(root) 主機名(localhost) 當前所在目錄(家目錄) 超級用戶提示符(#) 普通用戶提示符($) 1.1命令的格式 命令 [選項] [參數] 註意: 個別命令不是這種格式 多個選項可以寫在一起 簡寫選項 ...
  • 提示說沒有.git這樣一個目錄,解決辦法: 輸入 git init 就可以啦。 ...
  • 本文出自http://www.cnblogs.com/scoter2008 1、強大的官方文檔 2、按步驟來,先更新yum源,這裡用163的源 3、更新系統 4、如果遇到問題:Delta RPMs disabled because /usr/bin/applydeltarpm not install ...
  • ipcs 1. 命令格式 ipcs [resource-option] [output-format] ipcs [resource-option] -i id 2. 命令功能 提供IPC設備的信息 3. 使用方法 resource選項: ipcs -m 查看系統共用記憶體信息 ipcs -q 查看系 ...
  • 1.命令格式 find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression] 2. 命令功能 在文件目錄層級中查找文件並做相應的處理 3. 命令選項 -name finename 按照文件名查找文件,文件名可使用通配符 -per ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...