1. 程式人生 > >C#基礎知識整理 基礎知識(20) 委託(一)

C#基礎知識整理 基礎知識(20) 委託(一)

委託和事件在C#中使用很多,尤其在進行窗體程式設計時,很多的操作都要通過委託和事件來處理和傳遞。這裡詳細解釋下委託和事件的用法和原因,使我們在寫程式碼時能更加明白一些。
委託的使用
事件是一種機制,事件是通過委託實現的,所以看明白了委託,對於事件也就能更好的理解了。先看下面一個小例子。
這是描述不同語言的程式設計師的程式碼:
比如使用C#的程式設計師我們這樣描述,其中programerName引數表示這個程式設計師的姓名。

        public void CsharpProgramer(string programerName)
        {
            Console.WriteLine(string.Format("{0} 使用C#程式設計!", programerName));
        }

使用Java的,

        public void JavaProgramer(string programerName)
        {
            Console.WriteLine(string.Format("{0} 使用Java語言程式設計!"));
        }

那麼這麼多語言,怎麼區分這是哪個程式設計師呢?使用一個列舉來表示,

    public enum ProgramLanguage
    {
        CSharp,

        C,

        Java
    }

那麼進行一個完整的描述,程式碼如下:

   public class ProgramerDescription
    {
        //01
        public void CsharpProgramer(string programerName)
        {
            Console.WriteLine(string.Format("{0} 使用C#程式設計!", programerName));
        }

        public void CProgramer(string programerName)
        {
            Console.WriteLine(string.Format("{0}使用C語言程式設計!", programerName));
        }

        public void JavaProgramer(string programerName)
        {
            Console.WriteLine(string.Format("{0} 使用Java語言程式設計!"));
        }

        //02
        public void Description(string programerName, ProgramLanguage type)
        {
            switch (type)
            {
                case ProgramLanguage.CSharp:

                    CsharpProgramer(programerName);

                    break;

                case ProgramLanguage.C:

                    CProgramer(programerName);

                    break;

                case ProgramLanguage.Java:

                    JavaProgramer(programerName);

                    break;

                default:

                    Console.WriteLine("A kind of new Language that you never heard of.");

                    break;
            }
        }
    }

    public enum ProgramLanguage
    {
        CSharp,

        C,

        Java
    }

呼叫:

            ProgramerDescription pm = new ProgramerDescription();

            pm.Description("楊友山", ProgramLanguage.CSharp);

這時,輸出"楊友山 使用C#程式設計!";
這樣就初步完成了一個對程式設計師描述的簡單實現。這裡的Description方法是通過一個列舉型別來區別不同的語言。這樣它的維護性是比較差的,因為還有很多程式語言(C++,php,等),如果想加一種語言就要增加一個對應的方法,然後就要修改ProgramLanguage這個列舉型別。增加方法對原程式影響不大,因為可以用分部類來實現,而修改列舉就不合適了,這也不符合面向物件設計思想的開放封閉原則。
那麼在Description方法中怎麼處理呢,也就是不用枚舉了,Description方法如何來區分該呼叫哪個方法(CsharpProgramer,CProgramer,JavaProgramer)對程式設計師進行描述。
public void Description(string programerName, 某型別 某引數)
{
   //呼叫對應的方法
}
這裡的某型別就是要用它來區別哪個方法的型別,換句話說,最好就是在這裡我直接把我想要呼叫的方法當做引數傳進去。比如我要呼叫CProgramer方法來描述C程式設計師,
            ProgramerDescription pm = new ProgramerDescription();

            pm.Description("D.M.Ritchie", CProgramer);
按照這個想法,public string Description(string programerName, 某型別 某引數)的“某型別 某引數”該怎麼表示呢?
當然我們就想到C#中的委託delegate了。委託是一種資料結構,它引用靜態方法或引用類例項及該類的例項方法。 用委託來完成上述的程式碼:

    public class ProgramDescriptionDelegate
    {
        //委託,表示方法
        public delegate void DescriptionDelegate(string programerName);

        //01
        public void CsharpProgramer(string programerName)
        {
            Console.WriteLine(string.Format("{0} 使用C#程式設計!", programerName));
        }

        public void CProgramer(string programerName)
        {
             Console.WriteLine(string.Format("{0}使用C語言程式設計!", programerName));
        }

        public void JavaProgramer(string programerName)
        {
             Console.WriteLine(string.Format("{0} 使用Java語言程式設計!"));
        }

        //02
        public void Description(string programerName, DescriptionDelegate description)
        {
            description(programerName);
        }
    }

呼叫:

            ProgramDescriptionDelegate pm = new ProgramDescriptionDelegate();

            pm.Description("楊友山", pm.CsharpProgramer);

結果是和最開始的程式碼是一樣的。
什麼是委託?MSDN這樣解釋的:委託是一種定義方法簽名的型別,可以與具有相容簽名的任何方法關聯,可以通過委託呼叫方法。委託用於將方法作為引數傳遞給其他方法。時間處理程式就是通過委託呼叫的方法。

仔細看使用委託的程式碼,
public void Description(string programerName, DescriptionDelegate description)。呼叫時,
DescriptionDelegate description傳入的是 pm.CsharpProgramer,也就是此時description=pm.CsharpProgramer。其實我們還可以這樣呼叫:

                    //方法和委託繫結
            ProgramDescriptionDelegate pm = new ProgramDescriptionDelegate();

            YYS.CSharpStudy.Window.SDelegate.ProgramDescriptionDelegate.DescriptionDelegate

                csharpDelegate = pm.CsharpProgramer;

            YYS.CSharpStudy.Window.SDelegate.ProgramDescriptionDelegate.DescriptionDelegate

                cdelegate = pm.CProgramer;

            pm.Description("楊友山", csharpDelegate);

            pm.Description("D.M.Ritchie", cdelegate);

結果:

再做修改:

            ProgramDescriptionDelegate pm = new ProgramDescriptionDelegate();

            YYS.CSharpStudy.Window.SDelegate.ProgramDescriptionDelegate.DescriptionDelegate

                pdelegate = null;

            pdelegate += pm.CsharpProgramer;

            pdelegate += pm.CProgramer;

            pm.Description("楊友山", pdelegate);

結果:

這裡先執行了pm.CsharpProgramer,然後又執行了pm.CProgramer方法。
可以看出委託不光可以將方法作為引數,而且還可以將方法繫結,而起還可以繫結多個。
使用+=繫結方法,取消則使用-=進行取消,上面的呼叫可以修改如下:

            ProgramDescriptionDelegate pm = new ProgramDescriptionDelegate();

            YYS.CSharpStudy.Window.SDelegate.ProgramDescriptionDelegate.DescriptionDelegate

                pdelegate = null;

            pdelegate += pm.CsharpProgramer;

            pdelegate += pm.CProgramer;

            pdelegate -= pm.CProgramer;

            pm.Description("楊友山", pdelegate);

這樣就只調用pm.CsharpProgramer;一個方法了。

相關推薦

C#基礎知識整理 基礎知識20 委託

委託和事件在C#中使用很多,尤其在進行窗體程式設計時,很多的操作都要通過委託和事件來處理和傳遞。這裡詳細解釋下委託和事件的用法和原因,使我們在寫程式碼時能更加明白一些。 委託的使用 事件是一種機制,事件是通過委託實現的,所以看明白了委託,對於事件也就能更好的理解了。先看下面

C++核心知識點整理——基礎知識

尊重函式介面,儘量不作內部改動 C++程式碼語句分為:內建型別,名字,變數,操作符,標量,字串,預處理指示(如#include)等 C++中定義類來組織資料結構 標準庫的標頭檔案用尖括號 < > 括起來,非標準庫的標頭檔案用雙引號 ” ” 括起

執行緒八大基礎核心五執行緒相關方法

1.引子 在java多執行緒併發程式設計中,有八大基礎核心。考考你:看看都有哪八大基礎核心呢?它們分別是: 1.建立執行緒的方式 2.執行緒啟動 3.執行緒停止 4.執行緒生命週期 5.執行緒相關的方法 6.執行緒相關的屬性 7.執行緒異常處理 8.執行緒安全 今天我們從第五個基礎核心開始:執行緒相關方法 2

C++】內部類解決名字衝突問題

將內部類看成普通成員,符合普通成員的規則,用法就是正常類的使用方法。 定義內部類 把一個類的定義寫在另一個類的內部,則成裡面的這個類為內部類。例如,下面程式碼中的Inner類 #include <stdio.h> #include <string.h>

C/C++學習筆記整理】--3.取陣列中的其中位,將其中幾位組合起來

10.定義一個數組,取陣列中的其中幾位,將其中幾位組合起來 const int f[10]={6,2,5,5,4,5,6,3,7,6}; int match(int num) {     int k=0;     for(int i=n

LeetCode 堆疊佇列 —— 括號匹配20、232、155

1. 堆疊(stack) 20,20. Valid Parentheses,括號匹配,堆疊(python 中使用 list 即可實現表示堆疊,list.append:入棧,list.pop():出棧

C# 入門9 委託delegate,匿名方法,Lambda表示式

C#的委託,匿名方法,Lambda表示式   委託就像C++的函式指標一樣,可以指向一個函式,但委託更牛逼,指的其實是一個函式列表,依次執行函式。   在C++中,匿名方法和Lambda表示式其實是一回事,C#裡就是兩回事了。 委託 委託

當asp.net core偶遇docker模型驗證和Rabbitmq

  比如我們有一些設計,依賴於某些軟體,比如rabbitmq 當管理員功能,反覆錯誤三五次之後,就傳送一條訊息到佇列裡去,我們又不希望對原先設計帶來侵入式的改變業務 這個時候,我們就可以在模型驗證裡面加入一條衝向rabbitmq的程式碼了 既然是docker,還是先說說如何部署一個docke

小程式篇:mac搭建小程式本地測試伺服器

mac搭建小程式本地測試伺服器 根據教程逐步搭建:https://www.jianshu.com/p/61f50ee77dec 可能遇到的問題: npm未安裝,使用終端語句時報錯npm: command not found,參考教程安裝npm:https://blog.c

python進階資料分析numpy庫

numpy——基礎,以矩陣為基礎的數學計算模組,純數學儲存和處理大型矩陣。  這個是很基礎的擴充套件,其餘的擴充套件都是以此為基礎。 scipy——數值計算庫,在numPy庫的基礎上增加了眾多的數學、科學以及工程計算中常用的庫函式。  方便、易於使用、專為科學和工程設計的Py

selenium點選連結進入子頁面抓取內容新聞抓取案例

找了一個新聞網站練習爬蟲抓取,目標:逐一點選目錄標題,進入詳細新聞頁面,抓取子頁面的標題和正文內容並打印出來,返回目錄標題頁,點選下一篇文章。注:沒有新開視窗,是在原視窗實現跳轉。新開視窗進行抓取看下一篇文章。 試了很多種方法都抓取不到class=rightContent下

套接字與套接字描述符網路程式設計Linux_C -> 筆記

套接字與套接字描述符 什麼是套接字?   套接字是一種通訊機制,是支援TCP/IP網路通訊的基本單元。在之前得知套接字可以實現跨越網路的程序通訊(或者說位於不同計算機的程序通訊),但它最初是伯克利UNIX的一部分,用於的是同一主機上程序的通訊。由於它最初是伯克

MyBatis 關聯查詢一對多 & 多對

1、一對多 舉個例子:一個國家有很多人。一對多 1)表結構 -- 國家country CREATE TABLE `country` ( `cid` int(5) NOT NULL AUTO_INCREMENT, `cname` varchar(20) NOT N

比Switch case 更高效的方法:字典Dictionary + 委託delegate

Hello,我是KitStar 以下文章整理的不對。還請見諒 以下程式碼書寫於Unity3D中。 眾所周知,在C#中。一條switch語句允許測試一個變數在等於多個值的時的情況

TCP/IP的特性三次握手&四次揮手

    TCP與UDP的對比:      TCP/IP中有兩個具有代表性的傳輸協議,他們分別是TCP和UDP。TCP提供可靠的通訊傳輸,而UDP則常被用於廣播和細節控制交給應用的通訊傳輸。那他們有何異同呢? &nbs

產品經理之一產品需求的調研

             在我看來,一款自主研發的產品,需要把握很多的需求,比如:市場需求(主要是指產品的市場價值),產品需求(使用者需求),開發需求,主要就是這三個方面             1、市場需求:這點對於一個合格的產品經理來說,是非常重要的,需要具備洞察市場

STL常用的STL容器

常用的STL容器(每一個容器就是一個類模板,大致分為順序容器,介面卡容器,關聯容器。 1.順序容器(按照線性次序的位置儲存資料,即第一,第二,,第三,依次類推,常用的順序容器是vector,string,deque,list). (1)向量容器(vector) |v[0]|v[1]|v[2]

關於反射機制反射機制的理解

   在還不太熟悉反射的昨天,以為反射很神祕,在網上到處找答案.今天找了段程式碼敲了一下,茅塞頓開!其實反射也就那麼簡單的一回事!     反射是一種機制,通過這種機制我們可以知道一個未知型別的型別資訊.比如,有一個物件a,這個物件不是我們定義的,也許是通過網路捕捉到的,

Java反射機制的理解Spring學習鋪墊知識點

由於要學習Spring框架,所以先補充一波對Java反射機制原理的理解。 遇到一個問題或者概念,第一步就是要知道它的基本定義,然後再探尋它是什麼,怎麼用。 什麼是反射? Java 反射機制是在執行狀態中,對於任意一個類,都能夠獲得這個類的所有屬性和方法,對

031、none和host網絡的適用場景2019-02-18 周

fault ont rgba ifconfig ace 多個 scope 除了 cast 參考https://www.cnblogs.com/CloudMan6/p/7053617.html 本節開始,會學習docker的幾種原生網絡,以及如何創建自定義網絡。然後探