程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 委托學習筆記1:委托的基本使用,委托學習筆記1

委托學習筆記1:委托的基本使用,委托學習筆記1

編輯:C#入門知識

委托學習筆記1:委托的基本使用,委托學習筆記1


一、引子

在正式說委托前,我先給一個例子,然後引出後面要說的委托。

很簡單,就是一個機器人打招呼的。

代碼清單1.1:

class Robot { public void GreetByChinese(string name) { Console.WriteLine("你好," + name + "!"); } public void GreetByEnglish(string name) { Console.WriteLine("Hello," + name + "!"); } //打招呼 public void DoGreet(string name,string lang) { switch (lang) { case "chinese": GreetByChinese(name); break; case "english": GreetByEnglish(name); break; default: break; } } } class Program { static void Main(string[] args) { //實例化機器人對象 Robot robot = new Robot(); string name = Console.ReadLine(); robot.DoGreet(name,"chinese"); robot.DoGreet(name,"english"); Console.Read(); } } View Code

代碼清單1.1中創建了一個機器人類,類中封裝了兩個打招呼的方法和一個調用這兩個方法的公共方法。DoGreet方法中,只要帶name和switch中的條件,就可以打印出對應語言打招呼的語句。

那麼,如果我要增加其他的語言,如法語、日語、韓語等,我除了增加對應的方法,還需要改DoGreet方法裡的case語句,維護量較大。那有什麼辦法可以解決這種尴尬呢?

一種比較簡單的方法是,直接將方法作為參數(變量),傳給另一個方法(DoGreet),在其中執行即可。

但我們都知道,能作為方法的參數的是某一類型的對象或變量,而方法是個什麼類型呢?確實找不出方法對應的類型。但依然有種方法可以間接的將方法作為一個參數來使用,這便引出了,下面要提到的“委托”。 

二、關於委托,微軟給出的定義如下:

“委托用於將方法作為參數傳遞給其他方法。”

早在C#1.0時,就已開始支持這個特性(用過VS2003的園友,應該是最清楚不過了)。關於微軟給出的定義,已經很好理解了:我們利用委托,把方法作為一個參數(變量)傳遞給其他的方法,從而由其他方法來代為執行這個當做參數的方法裡的動作。 

三、那麼怎麼去使用委托呢?

使用委托,基本要按照如下步驟實現:

1、定義一個委托類型

訪問修飾符 delegate 返回類型 委托類型名稱(參數列表);

Ex:public delegate void Greet(string name);

2、創建一個執行某動作的方法(返回類型和參數列表須與委托類型相同)

訪問修飾符 返回類型 方法名稱(參數列表){......}

Ex:public void GreetByChinese(string name)

{

Console.WriteLine(“你好,”+name+“!”);

}

3、實例化委托類型

委托類型名稱 委托對象名稱=方法名稱;

Ex:Greet greet=GreetByChinese;

4、開始使用,執行操作

委托對象名稱(參數列表);

或:委托對象名稱.Invoke(參數列表);

Ex:greet(“季節旋風”);  或:greet.Invoke(“季節旋風”); 

如上,就這麼個簡單的流程,是不是很簡單。但這裡,可能有人會說,定義中不是將方法作為參數傳給另一個方法嗎?怎麼沒有這麼用?其實這個不用擔心,我們已經在步驟3中將方法引用給了greet對象,既然是對象,那麼久可以作為方法的參數,就可以很好地解決這個疑問。

具體的看下面的代碼清單3.1:

 

//一個常用的委托,打招呼 delegate void Greet(string name); //一個機器人類,封裝打招呼 class Robot { public void GreetByChiness(string name) { Console.WriteLine("你好," + name + "!"); } public void GreetByEnglish(string name) { Console.WriteLine("Hello," + name + "!"); } public void GreetByJapaness(string name) { Console.WriteLine("こんにちは," + name + "!"); } //打招呼 public void DoGreet(string name, Greet greet) { greet(name); } } class SampleDelegate { static void Main(string[] args) { //實例化機器人對象 Robot robot = new Robot(); string name = Console.ReadLine(); //通過把方法作為變量來實現打招呼 robot.DoGreet(name, robot.GreetByChiness); robot.DoGreet(name, robot.GreetByEnglish); robot.DoGreet(name, robot.GreetByJapaness); Console.Read(); } } View Code

 

執行結果如下:

 

依然是機器人大招呼的例子,但用到了委托,這樣一來是不是更簡潔了?這裡已經可以輕松地將方法作為參數傳遞給執行方法(DoGreet)中,並在其中執行操作。 

四、合並委托(多路廣播委托)

委托對象的一個有用屬性是:可以使用 “+” 運算符將多個對象分配給一個委托實例。 多播委托包含已分配委托的列表。 在調用多播委托時,它會按順序調用列表中的委托。 只能合並相同類型的委托。 “-” 運算符可用於從多播委托中移除組件委托。

依然用機器人打招呼的例子來講,這裡就不再使用DoGreet方法了,直接在Main方法中來做“打招呼”動作。如下(代碼清單4.1):

 

Greet greet = robot.GreetByChiness;
greet += robot.GreetByEnglish;
greet += robot.GreetByJapaness;
greet(name);

 

在運行時,它會按順序執行調用的方法,如下圖:

值得注意的是,只有對委托對象greet初始化後才可進行多播操作,例如下面的這種寫法就是錯誤的:

Greet greet+= robot.GreetByChiness;

在執行移除(“-”)操作時,跟合並操作類似,但它是從委托中移除已有的方法。例如將代碼清單4.1的代碼後面加上,下面代碼(代碼清單4.2):

 

Console.WriteLine("移除日語後:");
greet -= robot.GreetByJapaness;
greet(name);

 

那麼第二次greet時,會少一個日語問候,執行結果如下圖:

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved