C#基礎之委托

来源:https://www.cnblogs.com/qcst123/archive/2019/09/24/11575557.html
-Advertisement-
Play Games

通過以下思維導圖,學習委托的基本概念,後面著重講解委托的運用,希望通過最簡單的方式收穫更多的知識。 1.委托的各種寫法 1、委托 委托名=new 委托(會調用的方法名); 委托名(參數); 2、委托 委托名 =會調用的方法名; 委托名(參數); 3、匿名方法:委托 委托名=delegate(參數){ ...


  通過以下思維導圖,學習委托的基本概念,後面著重講解委托的運用,希望通過最簡單的方式收穫更多的知識。

1.委托的各種寫法

1、委托 委托名=new 委托(會調用的方法名); 委托名(參數);

2、委托 委托名 =會調用的方法名; 委托名(參數);

3、匿名方法:委托 委托名=delegate(參數){會調用的方法體};委托名(參數);

4、拉姆達表達式:委托 委托名=((參數1,。。參數n)=>{會調用的方法體});委托名(參數);

5、用Action<T>和Func<T>

Action<參數1, 參數2,> 委托名= ((參數1,參數2) => {不帶返回值的方法體 });委托名(參數1,參數2);

Func<參數1, 參數2, 返回值> 委托名= ((參數1,參數2) => {帶返回值的方法體 });返回值=委托名(參數1,參數2);

示例:

public delegate int Call(int num1, int num2);
class SimpleMath
{
    // 乘法方法
    public static int Multiply(int num1, int num2)
    {
        return num1 * num2;
    }

    // 除法方法
    public int Divide(int num1, int num2)
    {
        return num1 / num2;
    }
}


class Test
{
    static void Main(string[] args)
    {
        //--------------------第一種寫法------------------------//
        Call objCall = new Call(SimpleMath.Multiply);
        Call objCall1 = new Call(new SimpleMath().Divide);
        
        //--------------------第二種寫法------------------------//
        Call objCall = SimpleMath.Multiply;
        Call objCall1 = new SimpleMath().Divide;
        
        //--------------------第三種寫法------------------------//
        Call objCall = delegate(int a, int b)
        {
            return a * b;
        };
        Call objCall1 = delegate(int a, int b)
        {
            return a / b;
        };
        
        //--------------------第四種寫法------------------------//
        Call objCall =((int a,int b)=> { return a*b;});
        Call objCall1 = ((int a, int b) => { return a / b; });
        
        //--------------------第五種寫法------------------------//
        Func<int, int, int> objCall = ((a, b) => { return a * b; });
        Func<int, int, int> objCall1 = ((a, b) => { return a / b; });
        Action<int, int> ob = ((a, b) => { Console.WriteLine(a * b); });
        ob(5, 3);
        //----------------------------------------------------//
        
        int result = objCall(5, 3);
        int result1 = objCall1(5, 3);
        System.Console.WriteLine("結果1為 {0},結果2為{1}", result,result1);
        Console.ReadKey();
    }
}

 

2.委托的運用

委托的運用記住兩點:

1.將方法當作參數實例化委托對象;

 2.將方法的參數傳遞給委托對象,以實現實際的方法調用。

委托常用場景:

1.模板方法:

 如以下定義類CalculateFactory,用於定義各種計算方法,然後通過Calculate方法暴露出來給外界使用,而Calculate方法通過傳入委托對象new Calculate(x1.Add)來實現對Add方法的調用。這是委托模板方法使用較簡單的一種形式,它還可以有很多變種。

  下麵這段程式不用委托完全可以實現同樣的邏輯,為什麼要“故弄玄虛”呢?因為示例是為了說明委托作為模板方法的用法,故而用了最簡單的一種,實際運用過程中,通常與設計模式相結合,以實現代碼的高復用低耦合。進一步延伸,實際設計模式中也較少用委托,而用介面、抽象類來實現“模板方法”的功能,具體要怎麼用是看個人習慣和便捷程度。委托用的最多的場景是下麵要介紹的回調方法。

 class Program
    {
        static void Main(string[] args)
        {
            CalculateFactory x1 = new CalculateFactory();
            CalculateFactory x2 = new CalculateFactory();
            x1.Calculate(10, 9, new Calculate(x1.Add));
            x2.Calculate(10, 9, new Calculate(x2.Reduce));
            Console.ReadKey();
        }
    }


    public delegate void Calculate(int a, int b);
    public class CalculateFactory
    {
        public void Calculate(int a, int b, Calculate calculateDelegae)
        {
            calculateDelegae(a, b);
        }

        public void Add(int a, int b)
        {
            Console.WriteLine(string.Format("This is a+b={0}", a + b));
        }

        public void Reduce(int a, int b)
        {
            Console.WriteLine(string.Format("This is a-b={0}", a - b));
        }

    }

 

2.回調方法:

  回調方法與模板方法並不是併列的兩種類型,其本質都是一樣的,即將方法當成參數傳遞並調用,是通過應用場景來分類的。主調方法(調用回調方法的方法體)在滿足某種條件或完成某種邏輯後去調用的方法,稱為回調方法。將上面示例改造成含有回調方法的程式。

示例:這裡既用到了模板方法,也用到了回調方法。示例代碼來源於劉鐵猛大師的示例,在此表示感謝。

 class Program
    {
        static void Main(string[] args)
        {
            ProductFactory productFactory = new ProductFactory();
            WrapFactory wrapFactory = new WrapFactory();

            Func<Product> func1 = new Func<Product>(productFactory.MakePizza);
            Func<Product> func2 = new Func<Product>(productFactory.MakeToyCar);

            Logger logger = new Logger();
            Action<Product> log = new Action<Product>(logger.Log); //Log的委托;

            Box box1 = wrapFactory.WrapProduct(func1, log);
            Box box2 = wrapFactory.WrapProduct(func2, log);

            Console.WriteLine(box1.Product.Name);

        }
        class Product //產品類
        {
            public string Name { get; set; }
            public double Price { get; set; }
        }
        class Box //盒子類
        {
            public Product Product { get; set; }
        }
        class Logger
        {
            public void Log(Product product)
            {
                Console.WriteLine(product.Price);
            }
        }
        class WrapFactory  //包裝工廠
        {
            public Box WrapProduct(Func<Product> getProduct, Action<Product> logCallback)
            {
                Box box = new Box();
                Product product = getProduct.Invoke();//此處使用的是間接的同步調用,如果使用間接非同步調用用BeginInvoke();
                if (product.Price > 50) //如果產品價格大於50,就執行回調方法;
                {
                    logCallback(product);
                }
                box.Product = product;
                return box;
            }
        }
        class ProductFactory  //產品工廠
        {
            public Product MakePizza()
            {
                Product product = new Product();
                product.Name = "Pizza";
                product.Price = 30;
                return product;
            }
            public Product MakeToyCar()
            {
                Product product = new Product();
                product.Name = "ToyCar";
                product.Price = 100;
                return product;
            }
        }
    }

 

3.總結

   委托基礎內容基本就是這些,回調方法在實際使用中也是最多的,上面回調方法的示例是有實用價值的,需要好好體會。委托還有多播委托等進階應用,在此不作介紹,但需要瞭解其概念,以便碰到相應場景時翻翻資料能找到解決方案。

 


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

-Advertisement-
Play Games
更多相關文章
  • 今天這Class文件看的我一臉懵圈。有種當初學PE時候的感覺了。 類文件結構 如果電腦的CPU指令集只有X86一種,操作系統也只有windows,那也許Java語言就不會出現。Java在誕生之初就提出一個非常著名的口號:一次編寫到處運行。 class文件的結構 Class文件是一組以8位位元組為基礎 ...
  • 一、使用Servlet配置 二、使用Listener配置 三、使用Filter配置 ...
  • 連接類型:1、 JDBC OCI: oci是oracle call interface的縮寫,此驅動類似於傳統的ODBC 驅動。因為它需要Oracle Call Interface and Net8,所以它需要在運行使用此驅動的JAVA程式的機器上安裝客戶端軟體,其實主要是用到orcale客戶端里以 ...
  • 談談枚舉 [TOC] 如果一個類的對象個數是有限的而且是不變的,我們通常將這樣的類設計成枚舉類。 1. 枚舉類的定義 枚舉類有如下特點: 枚舉類預設是使用final關鍵字修飾的,所以枚舉類不能被繼承; 枚舉類的構造函數預設是使用private修飾的; 定義枚舉類時所有實例必須在第一行全部列出; 枚舉 ...
  • 第一步 接下來我們將看見如何在 Python 中運行一個傳統的“Hello World”程式。Python教程本章將會教你如何編寫、保存與運行 Python 程式。 通過 Python 來運行的你的程式有兩種方法——使用互動式解釋器提示符或直接運行一個源代碼文件。我們將瞭解如何使用他們二者的功能。 ...
  • 在應用中需要使用調度框架來做一些統計的功能,可惜在Windows上可用的不多,最後選擇了APScheduler這個調度器。 用法不多介紹,只總結一下在使用中遇到的坑。 app_context 問題 凡是在APScheduler中調用的function,只要用到初始化跟app相關的對象(如db,mai ...
  • 一、迴圈 輸入一個數字,輸出該數字有幾位 二、while迴圈 迴圈體內要有改變條件的機會,避免死迴圈 while迴圈的意思就是:當條件滿足時,不斷地重覆迴圈體內的語句 迴圈執行之前判斷是否繼續迴圈,所以有可能迴圈一次也沒有被執行 看我們上面的代碼,是否有點多餘的成分,我們來進行改造,但是還有一個問題 ...
  • # 深淺拷貝 1 import copy 2 3 a = ["xiaoming",111,[5000,2000]] 4 b = a 5 print("b:%s" % b) #a,b共用同一塊記憶體地址,輸出結果b:['xiaoming', 111, [5000, 2000]] 6 7 #淺拷貝只拷貝第 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...