C#事件和委托(C#學習筆記03)

来源:https://www.cnblogs.com/asahiLikka/archive/2019/10/09/11644393.html
-Advertisement-
Play Games

委托 1. C# 中的委托類似於 C 或 C++ 中指向函數的指針。委托表示引用某個方法的引用類型變數,運行時可以更改引用對象。 2. 特別地,委托可以用於處理事件或回調函數。並且,所有的委托類都是從 System.Delegate 類繼承而來。 聲明委托的語法規則:(被委托所引用的方法需有相同的參 ...


委托

1. C# 中的委托類似於 C 或 C++ 中指向函數的指針。委托表示引用某個方法的引用類型變數,運行時可以更改引用對象。
2. 特別地,委托可以用於處理事件或回調函數。並且,所有的委托類都是從 System.Delegate 類繼承而來。

聲明委托的語法規則:(被委托所引用的方法需有相同的參數和返回值)

delegate <return type> <delegate-name> <parameter list>

 

一個委托使用示例:

using System;

public delegate void Mydelegate(string str);                //創建委托實例

namespace Delegate
{
    class TextMethods

    {
        public static void Method1(string str)
        {
            Console.WriteLine("這是方法1,{0}",str);
        }

        public static void Method2(string str)

        {
            Console.WriteLine("這是方法2,{0}",str);
        }

        public static void Method3(string str)
        {
            Console.WriteLine("這是方法3,{0}", str);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Mydelegate d1, d2, d3;                               //定義委托變數

            d1 = TextMethods.Method1;

            d2 = TextMethods.Method2;

            d3 = TextMethods.Method3;

            d1("1");                                             //調用委托實例

            d2("2");

            d3("3");

            Console.WriteLine("");

            Mydelegate d4;

            d4 = TextMethods.Method1;

            d4 += TextMethods.Method2;                          //添加實例

            d4 += TextMethods.Method3;

            d4("4");

            Console.WriteLine("");

            d4 -= TextMethods.Method3;                          //移除實例

            d4("5");

            Console.WriteLine("");
        }
    }
}

 

事件

事件是應用程式在執行過程中所關註的一些動作,但這些動作發生時,程式需要對其做出響應。事件的概念比較廣泛,所有程式需要進行響應處理的動作都可以稱為事件。如滑鼠單擊、鍵盤輸入、計時器消息...

事件基於委托,為委托提供了一種發佈/訂閱機制,在.NET架構內外都可以看到事件。在Windows應用程式中,Button類提供了Click事件。這類事件就是委托,觸發Click事件調用的處理程式需要得到定義,而其參數由委托類型定義。

事件機制是以消息為基礎的,當特定的動作發生後會產生相應的消息,關註該事件的應用程式收到事件發生的消息,就會開始指定處理過程。

示例:

參考自:[w3cSchool] https://www.w3cschool.cn/wkcsharp/yvoj1nvx.html"%3Ehttps://www.w3cschool.cn/wkcsharp/yvoj1nvx.html%3C/a%3E

該示例為一個簡單的應用程式,該程式用於熱水鍋爐系統故障排除。當維修工程師檢查鍋爐時,鍋爐的溫度、壓力以及工程師所寫的備註都會被自動記錄到一個日誌文件中。
示例中可以看出,在主函數中,創建了事件發佈器類(DelegateBoilerEvent),並將一個寫入文檔的(訂閱器)和一個控制台輸出函數添加進事件示例中。在執行觸發器類中的記錄過程函數(LogProcess() )時,就會調用所有添加進事件的函數實例。

 

using System;
using System.IO;

namespace BoilerEventAppl
{
    // boiler 類
    class Boiler
    {
        private int temp;                             //鍋爐溫度
        private int pressure;                         //鍋爐壓力
        public Boiler(int t, int p)                   //構造函數
        {
            temp = t;
            pressure = p;
        }

        public int getTemp()
        {
            return temp;
        }

        public int getPressure()
        {
            return pressure;
        }
    }

    // 事件發佈器
    class DelegateBoilerEvent
    {
        public delegate void BoilerLogHandler(string status);            //聲明委托

        // 基於上述委托定義事件
        public event BoilerLogHandler BoilerEventLog;

        public void LogProcess()                                         //記錄過程
        {
            string remarks = "O. K";
            Boiler b = new Boiler(100, 12);
            int t = b.getTemp();
            int p = b.getPressure();
            if (t > 150 || t < 80 || p < 12 || p > 15)                  
            {
                remarks = "Need Maintenance";
            }
            OnBoilerEventLog("Logging Info:\n");
            OnBoilerEventLog("Temparature " + t + "\nPressure: " + p);
            OnBoilerEventLog("\nMessage: " + remarks);
        }

        protected void OnBoilerEventLog(string message)      //函數在發佈器類中,當要進行發佈時,就觸發事件BoilerEventLog所添加的實例
        {
            if (BoilerEventLog != null)                                                         
            {
                BoilerEventLog(message);
            }
        }
    }

    // 該類保留寫入日誌文件的條款
    class BoilerInfoLogger
    {
        FileStream fs;
        StreamWriter sw;
        public BoilerInfoLogger(string filename)
        {
            fs = new FileStream(filename, FileMode.Append, FileAccess.Write);
            sw = new StreamWriter(fs);
        }

        public void Logger(string info)     //信息寫入文檔
        {
            sw.WriteLine(info);
        }

        public void Close()
        {
            sw.Close();
            fs.Close();
        }
    }

    // 事件訂閱器
    public class RecordBoilerInfo
    {
        static void Logger(string info)           //控制台輸出信息
        {
            Console.WriteLine(info);
        }//end of Logger

        static void Main(string[] args)
        {
            BoilerInfoLogger filelog = new BoilerInfoLogger("‪boiler.txt");  //打開日誌文件
            DelegateBoilerEvent boilerEvent = new DelegateBoilerEvent();    //實例化DelegateBoilerEvent類,事件發佈器
            boilerEvent.BoilerEventLog += new
            DelegateBoilerEvent.BoilerLogHandler(Logger);                   //boilerEvent.BoilerEventLog為委托的實例,將Logger添加進委托
            boilerEvent.BoilerEventLog += new
            DelegateBoilerEvent.BoilerLogHandler(filelog.Logger);           //filelog是BoilerInfoLogger類的實例化,將其中的Logger函數添加進委托
            boilerEvent.LogProcess();                                       //執行LogProccess函數
            filelog.Close();
        }//end of main

    }//end of RecordBoilerInfo
}

 

 

執行結果:

Logging Info:

Temparature 100
Pressure: 12

Message: O. K

 


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

-Advertisement-
Play Games
更多相關文章
  • 小文:今天面試又搞砸了? 小 k:怎麼了? 小文:又一個大小寫轉換的題目感覺答錯了。 小 k:說來聽聽。 小文:將"hello world"轉換為首字母大寫"Hello World" 小 k:你的答案是什麼? 小文:用 capitalize 方法啊。 小 k:capitalize 方法只能將第一個單 ...
  • 本文主要講解Spring的基礎環境搭建以及演變由來,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 實驗環境:WIN7虛擬機 軟體:VC6 首先在VC6裡面寫一個空函數Fun(); F7編譯運行一下,沒有出錯,接著在函數處使用F9下斷點,使程式運行到Fun函數時停下。 接著F5開始運行這個程式 程式停在了Fun函數處,反彙編進去進行逆向分析 可以看到程式停在Fun函數的入口處,這裡的call就是F ...
  • 摘要 在 "詳解http報文" 一文中,詳細介紹了http報文的文本結構。那麼作為服務端,web容器是如何解析http報文的呢?本文以jetty和undertow容器為例,來解析web容器是如何處理http報文的。 在前文中我們從概覽中可以瞭解到,http報文其實就是一定規則的字元串,那麼解析它們, ...
  • composer是什麼 composer是PHP的插件依賴管理工具,我個人感覺和java的Maven、Gradle很類似。 Windows OS下安裝composer 參考: https://www.php.cn/php weizijiaocheng 400785.html https://blog ...
  • 聊起中斷,大家可能最熟悉的例子就是線程休眠。下麵就是一個線程休眠的 demo,在這個例子中,當我們調用 方法,該方法將會拋出一個需要捕獲的中斷異常,這裡捕獲該異常並直接返回。 java for (int i = 0; i An interrupt is an indication to a thre ...
  • 使用Mybatis查詢客戶端信息 前面的例子使用了預設的jdbc配置來動態從資料庫查詢客戶端信息,下麵來改用更加靈活的mybatis來實現,改用mybatis,首先pom中換成mybatis的依賴: 然後新建一個實體類,並實現查詢需要的 ClientDetails 介面: 由於介面預設需要實現的方法 ...
  • 類型和變數 [C#類型和變數(原文參考官方教程)]https://docs.microsoft.com/zh-cn/dotnet/csharp/tour-of-csharp/types-and-variables C#有兩種類型: 1. 值類型 1. 簡單類型 2. 枚舉類型 格式為 enum E ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...