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
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...