(轉)C#委托的介紹(delegate、Action、Func、predicate)

来源:http://www.cnblogs.com/hareis/archive/2016/10/24/5992678.html
-Advertisement-
Play Games

轉自(http://www.cnblogs.com/zhangchenliang/p/4968779.html) 委托是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞。事件是一種特殊的委托。 1.委托的聲明 (1). delegate delegate我們常用到的一種聲明 ... ...


轉自(http://www.cnblogs.com/zhangchenliang/p/4968779.html

 

委托是一個類,它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞。事件是一種特殊的委托。

  1.委托的聲明

  (1). delegate

        delegate我們常用到的一種聲明

   Delegate至少0個參數,至多32個參數,可以無返回值,也可以指定返回值類型。

   例:public delegate int MethodtDelegate(int x, int y);表示有兩個參數,並返回int型。

  (2). Action

       Action是無返回值的泛型委托。

   Action 表示無參,無返回值的委托

   Action<int,string> 表示有傳入參數int,string無返回值的委托

  Action<int,string,bool> 表示有傳入參數int,string,bool無返回值的委托

       Action<int,int,int,int> 表示有傳入4個int型參數,無返回值的委托

   Action至少0個參數,至多16個參數,無返回值。

   例:

        public void Test<T>(Action<T> action,T p)
        {
            action(p);
        }

    (3). Func

   Func是有返回值的泛型委托

   Func<int> 表示無參,返回值為int的委托

   Func<object,string,int> 表示傳入參數為object, string 返回值為int的委托

   Func<object,string,int> 表示傳入參數為object, string 返回值為int的委托

   Func<T1,T2,,T3,int> 表示傳入參數為T1,T2,,T3(泛型)返回值為int的委托

   Func至少0個參數,至多16個參數,根據返回值泛型返回。必須有返回值,不可void

      例:   

        public int Test<T1,T2>(Func<T1,T2,int>func,T1 a,T2 b)
        {
            return func(a, b);
        }

    (4) .predicate

   predicate 是返回bool型的泛型委托

   predicate<int> 表示傳入參數為int 返回bool的委托

   Predicate有且只有一個參數,返回值固定為bool

   例:public delegate bool Predicate<T> (T obj)

 2.委托的使用

(1).Delegate的使用  

 

        public delegate int MethodDelegate(int x, int y);
        private static MethodDelegate method;
        static void Main(string[] args)
        {
            method = new MethodDelegate(Add);
            Console.WriteLine(method(10,20));
            Console.ReadKey();
        }

        private static int Add(int x, int y)
        {
            return x + y;
        }

 

  (2).Action的使用   

 

 static void Main(string[] args)
        {
            Test<string>(Action,"Hello World!");
            Test<int>(Action, 1000);
            Test<string>(p => { Console.WriteLine("{0}", p); }, "Hello World");//使用Lambda表達式定義委托
            Console.ReadKey();
        }
        public static void Test<T>(Action<T> action, T p)
        {
            action(p);
        }
        private static void Action(string s)
        {
            Console.WriteLine(s);
        }
        private static void Action(int s)
        {
            Console.WriteLine(s);
        }

 

  可以使用 Action<T1, T2, T3, T4> 委托以參數形式傳遞方法,而不用顯式聲明自定義的委托。 封裝的方法必須與此委托定義的方法簽名相對應。 也就是說,封裝的方法必須具有四個均通過值傳遞給它的參數,並且不能返回值。 (在 C# 中,該方法必須返回 void)通常,這種方法用於執行某個操作。

  (3).Func的使用

 

        static void Main(string[] args)
        {
            Console.WriteLine(Test<int,int>(Fun,100,200));
            Console.ReadKey();
        }
        public static int Test<T1, T2>(Func<T1, T2, int> func, T1 a, T2 b)
        {
            return func(a, b);
        }
        private static int Fun(int a, int b)
        {
            return a + b;
        }

 

  (4). predicate的使用

  泛型委托:表示定義一組條件並確定指定對象是否符合這些條件的方法。此委托由 Array 和 List 類的幾種方法使用,用於在集合中搜索元素。

 

        static void Main(string[] args)
        {
            Point[] points = { new Point(100, 200), 
            new Point(150, 250), new Point(250, 375), 
            new Point(275, 395), new Point(295, 450) };
            Point first = Array.Find(points, ProductGT10);
            Console.WriteLine("Found: X = {0}, Y = {1}", first.X, first.Y);
            Console.ReadKey();
        }
        private static bool ProductGT10(Point p)
        {
            if (p.X * p.Y > 100000)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

 

  使用帶有 Array.Find 方法的 Predicate 委托搜索 Point 結構的數組。如果 X 和 Y 欄位的乘積大於 100,000,此委托表示的方法 ProductGT10 將返回 true。Find 方法為數組的每個元素調用此委托,在符合測試條件的第一個點處停止。

3.委托的清空

  (1).在類中申明清空委托方法,依次迴圈去除委托引用。

         方法如下:

 

 

      public MethodDelegate OnDelegate;                
        public void ClearDelegate()        
        {             
            while (this.OnDelegate != null) 
            {                 
                this.OnDelegate -= this.OnDelegate;  
            }        
        } 

 

  (2).如果在類中沒有申明清空委托的方法,我們可以利用GetInvocationList查詢出委托引用,然後進行去除。  

  方法如下:

 

 

        public MethodDelegate OnDelegate; 
     static void Main(string[] args) { Program test = new Program(); if (test.OnDelegate != null) { System.Delegate[] dels = test.OnDelegate.GetInvocationList(); for (int i = 0; i < dels.Length; i++) { test.OnDelegate -= dels[i] as MethodDelegate; } } }

 

  4.委托的特點

  委托類似於 C++ 函數指針,但它們是類型安全的。
  委托允許將方法作為參數進行傳遞。
  委托可用於定義回調方法。
  委托可以鏈接在一起;例如,可以對一個事件調用多個方法。
  方法不必與委托簽名完全匹配。

  5.總結:

Delegate至少0個參數,至多32個參數,可以無返回值,也可以指定返回值類型

  Func可以接受0個至16個傳入參數,必須具有返回值

  Action可以接受0個至16個傳入參數,無返回值

  Predicate只能接受一個傳入參數,返回值為bool類型

 

最後說下看完這些個自己用到的的感受  ,可以把 核心處理業務邏輯獨立出來 ,不用 一個函數一個方法的去寫


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

-Advertisement-
Play Games
更多相關文章
  • 從零開始配置ubuntu 14.04,記錄配置服務的過程,安裝組件如下: - SSH - curl - Git - MongoDB - Node.js - ... ...
  • 1.安裝phpStorm,步驟略 2.安裝xampp: 2.1 我下載的版本為:XAMPP 5.6.24(下載最新版裡面沒有xdebug.so文件) 照步驟安裝。 2.2 安裝成功後,啟動一下,看看是否可以運行,在瀏覽器地址欄輸入localhost,查看是否可以進入到xampp網站 。 2.3 點擊 ...
  • 嗬!沒想到吧!學習 Linux 的第三天,我們已經開始接觸用戶管理,用戶組管理,以及許可權管理這幾個逼格滿滿的關鍵字。這幾個關鍵字對於前端程式猿的我來說真的是很高大上有木有,以前嘗試學 Linux 的時候看到這些名詞總是下意識的跳過不敢看有木有,一提起這幾個名詞馬上腦海中總是升騰起無限的崇拜有木有!今 ...
  • 文檔目錄 本節內容: 實體類 聚合根類 領域事件 約定的介面 審計 軟刪除 活躍/消極 實體 實體變化事件 IEntity 介面 領域事件 審計 軟刪除 活躍/消極 實體 實體是DDD一個核心的概念。Eric Evans是這麼描述的:“一個對象根本上不是按它的特性定義的,而是按一個線程的連續性和身份 ...
  • 在做項目的時候,需要輸出資料庫操作的耗時,自己寫了個方法。老大看到後,奇怪我為什麼不用現成的。才知道有StopWatch這個類。 屬性 名稱說明 Elapsed 獲取當前實例測量得出的總運行時間。 ElapsedMilliseconds 獲取當前實例測量得出的總運行時間(以毫秒為單位)。 Elaps ...
  • mvc 碰到 從客戶端(Msg=&quot;...=&quot;pc}oDGY1&lt;h&quot;)中檢測到有潛在危險的 Reque...&quot;)中檢測到有潛在危險的 Request.QueryString 具體參數值 pc}oDGY1<h 引起的錯誤 從網上查在方法前加 [Validat ...
  • .NetCore MVC中的路由(1)路由配置基礎 0x00 路由在MVC中起到的作用 前段時間一直忙於別的事情,終於搞定了繼續學習.NetCore。這次學習的主題是MVC中的路由。路由是所有MVC框架都會實現的一個組件,核心功能就是根據接收到的Http請求中的Path(對於http://local ...
  • 一、Enable-Migrations 說明:為項目啟用遷移。此命令為項目添加Migrations文件夾,其中包括兩個文件: Configuration類:此類允許針對上下文配置遷移的行為 InitialCreate遷移:此遷移在啟用遷移之前生成。如果在啟用遷移之前沒有生成資料庫,則不會將此文件加入 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...