C# 委托 事件

来源:https://www.cnblogs.com/loverwangshan/archive/2018/12/20/10153171.html
-Advertisement-
Play Games

一:什麼叫委托 通過反射發現,委托其實是一個類,繼承自System.MulticastDelegate,但是System.MulticastDelegate這個類是特殊類,不能被繼承 二:委托的聲明 委托可以聲明在類外面,可以聲明再類裡面 三:委托的實例和調用 private int GetSome ...


一:什麼叫委托

通過反射發現,委托其實是一個類,繼承自System.MulticastDelegate,但是System.MulticastDelegate這個類是特殊類,不能被繼承

 

二:委托的聲明 

 public delegate void NoReturnNoParaOutClass();
 public class MyDelete
 {
      public delegate void NoReturnNoPara<T>(T t);
      public delegate void NoReturnNoPara();
      public delegate void NoReturnWithPara(int x, int y);
      public delegate int WithReturnNoPara();
      public delegate string WithReturnWithPara(out int x, ref int y);
    }

委托可以聲明在類外面,可以聲明再類裡面

 

三:委托的實例和調用 

      private int GetSomething()
        {
            return 1;
        }
        private int GetSomething2()
        {
            return 2;
        }

        private int GetSomething3()
        {
            return 3;
        }
        private void DoNothing()
        {
            Console.WriteLine("This is DoNothing");
        }
        private static void DoNothingStatic()
        {
            Console.WriteLine("This is DoNothingStatic");
        }
        public string ParaReturn(out int x, ref int y)
        {
            throw new Exception();
        }
View Code

 

//多種途徑實例化,要求傳遞一個參數類型,返回值都跟委托一致的方法
{
   WithReturnWithPara method = new WithReturnWithPara(ParaReturn);
   int x = 0;
   int y = 0;
   var dd = method.Invoke(out x, ref y);
 }
//begininvoke
{
   WithReturnNoPara method = new WithReturnNoPara(this.GetSomething);
   int iResult = method.Invoke();
   iResult = method();
   var result = method.BeginInvoke(null, null);//非同步調用
   method.EndInvoke(result);
}
{
   NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);
   //委托實力的調用,參數和委托約束的一致
    method.Invoke(); //1
    //method(); //2
    //method.BeginInvoke(null, null); //3
    //this.DoNothing(); //1,2,3都等同於this.DoNothing

}
{
     NoReturnNoPara method = new NoReturnNoPara(DoNothingStatic);
}
{
    NoReturnNoPara method = new NoReturnNoPara(Student.StudyAdvanced);
}
{
    NoReturnNoPara method = new NoReturnNoPara(new Student().Study);
}

 

四:為什麼要使用委托

有時候我們聲明一個方法,直接調用蠻好的,為啥還要使用委托,然後還要先聲明,再實例化,再inovke調用呢?

下麵我們舉個例子,比如一個人問好這件事情,不同人問候方式不一樣,我們會先定義一個類型,如枚舉

public enum PeopleType
 {
        Chinese,
        America,
        Japanese
 }

然後通過不同的類型來判斷問候方式不同,如下

        /// 為不同的人,進行不同的問候
        /// 傳遞變數--判斷一下----執行對應的邏輯
        /// </summary>
        /// <param name="name"></param>
        /// <param name="peopleType"></param>
        public void SayHi(string name, PeopleType peopleType)
        {
            switch (peopleType)
            {
                case PeopleType.Chinese:
                    Console.WriteLine($"{name}晚上好");
                    break;
                case PeopleType.America:
                    Console.WriteLine($"{name},good evening");
                    break;
                case PeopleType.Japanese:
                    Console.WriteLine($"{name},&&%*^^***@@@&&&&");
                    break;
                default:
                    throw new Exception("wrong peopleType"); //遇到異常報錯
            }
        }

這樣做的好處是:以後如果增加公共邏輯等比較容易,但是如果類型比較多,這個方法會變成無限制改動,導致方法難以維護,於是很多人想著增加分支,就增加方法--不影響別的方法的思路來改善

  public void SayHiChinese(string name)
  {
         Console.WriteLine($"{name}晚上好");
  }
  public void SayHiJapanese(string name)
  {
         Console.WriteLine($"{name},&&%*^^***@@@&&&&");
  }
  public void SayHiAmerican(string name)
  {
          Console.WriteLine($"{name},good evening");
  }

然後上層判斷調用

這樣做的好處是:修改某個方法--不影響別的方法 ,但是缺點卻是:增加公共邏輯---多個方法就有很多重覆代碼

那麼我們想:既增加邏輯方便,又維護簡單,魚肉熊掌,如何兼得呢?

我們可以把相應的邏輯做為參數傳進來,這樣就解決了我們的問題

具體我們可以按照以下來做:

  public void SayHiPerfact(string name, SayHiDeletegate method)
  {
      Console.WriteLine("增加開始日誌");
      method.Invoke(name);
      Console.WriteLine("增加結束日誌");          
  }
  public delegate void SayHiDeletegate(string name);

然後調用的時候如下:

  SayHiDeletegate method = new SayHiDeletegate(SayHiChinese);

這樣就做到了

1:邏輯解耦,方便維護 

2:代碼重構,去掉重覆

其實這也是我們選擇使用委托的兩大優點

註意:以上我們純粹為了定義委托而定義委托,其實框架已經我們幫我們定義了Action 和Func這兩個委托,Action是沒有返回值,Func是有返回值的,這兩個委托類已經足夠我們使用了,所以有時候我們使用的時候,沒有必要自己再去定義,而直接使用即可

 


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

-Advertisement-
Play Games
更多相關文章
  • @Html.Raw 定義:在有些情況下,需要顯式地渲染一些不應該採用HTML編碼的值,這時可以採用Html.Raw方法來保證該值不被編碼;簡單來說:就是使用了Html.Raw後,字元串會以一個html方式呈現,而不使用該方法字元串會以原始字元串的形式出現。 eg: 效果如下(註意上下順序與view中 ...
  • RenderBody 在Razor引擎中沒有了“母版頁”,取而代之的是叫做“佈局”的頁面(_Layout.cshtml)放在了共用視圖文件夾中。在這個頁面中,會看到 標簽里有這樣一條語句: 其實它的作用和母版頁中的伺服器控制項類似,當創建基於此佈局頁面的視圖時,視圖的內容會和佈局頁面合併,而新創建視圖 ...
  • 使用mvc綁定表單 每次綁定的對象都為null,查看Request.Form裡面是有傳進去的參數的,並且屬性名稱完全一樣,最後發現是 變數的命名不能和屬性裡面的欄位一樣 一樣的話綁定表單失敗 ...
  • C# -- 使用 Task 執行多線程任務 1. 使用 Task 執行多線程任務 執行結果: 2. 等待Task多線程任務執行完成 執行結果: ...
  • "Asp.NetCore程式發佈到CentOs(含安裝部署netcore) 最佳實踐(一)" 接上一篇 3. Nginx配置反向代理 3.1 cnetos 安裝nginx 首先,我們需要在伺服器上安裝Nginx。 "參考網址" 3.1.1:添加Nginx存儲庫 要添加CentOS 7 EPEL倉庫, ...
  • 前言 & 問題 如下截圖,TextBox,在觸摸點擊後,會自動彈出windows的虛擬鍵盤。 如何,禁用鍵盤的自動彈出? 調用虛擬鍵盤 通過調用TapTip.exe或者osk.exe,主動彈出虛擬鍵盤 詳細調用可參考:c#調用windows虛擬鍵盤 如何禁用鍵盤的彈出 TextBox在觸摸點擊後,會 ...
  • 以下內容為網路摘抄和實踐修改所得,如有雷同,請諒解!!!! 1、首先是前端頁面代碼: 其中,<input type="file" id="file_input" name="filePath" multiple="multiple"/> ,需要設置multiple屬性 <style type="te ...
  • 當我們在做項目的時候,引用js或者css是通常會在後面加上時間戳,舉例如下: v的後面就是引用的時間戳,那麼時間有什麼作用,該如何定義了?具體如下>> 時間戳的作用 好多Linux + Apache的伺服器都會對CSS、JS和圖片這些靜態的內容設置緩存,到了IE這裡又會在本地做一個緩存。所以當我們更 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...