一,聲明委托
對于委托,定義它就是要告訴編譯器,這種類型的委托表示哪種類型的方法.然后,必須創建該委托的一個或多個委托實例,編譯器將在后臺創建表示該委托的一個類.
因為定義委托基本上是定義一個新類,所以可以在定義類的任何相同地方定義委托.
在 術語 方面,和"類,對象"不同."類"表示的是較為廣義的定義,"對象"表示類的實例.但是委托只有一個術語,在創建委托實例時,所創建的 委托的實例 仍然稱為 委托 .
如下顯示委托的聲明方式:
//聲明委托. private delegate string GetAString();
?
二,使用委托
如下例子:
1 int x = 5 ; 2 // 通過委托的方式. 3 GetAString stringMethod = new GetAString(x.ToString); 4 Console.WriteLine(stringMethod());
也可以使用 委托推斷 ,只需將地址傳遞給委托類型的變量(在后臺,C#編譯器會做同樣的處理,即會在后臺創建一個委托實例 " new GetAString(x.ToString)"):
1
//
使用委托推斷,只需將地址傳遞給委托實例.
2 GetAString secondMethod = x.ToString;
實際上,調用委托時,給委托實例提供圓括號與調用委托的Invoke()方法,是完全相同的:
1 Console.WriteLine(stringMethod()); // 委托方式1(使用圓括號的方式). 2 Console.WriteLine(stringMethod.Invoke()); // 委托方式2(使用調用Invoke()方法的方式).
原因是對于委托變量stringMethod,C#編譯器會調用stringMethod.Invoke()代替stringMethod().
值得注意的是,在給一個委托類型的變量賦值的時候,方法的名稱不能帶有"()"括號,上述例子,調用 x.ToString()方法,會返回一個不能賦予委托變量的字符串對象(而不是方法的地址).
委托的一個特征是,它們是類型安全的,可以確定被調用的方法的簽名是正確的.但是委托不關心在什么類型上調用改方法,甚至不考慮方法是靜態的,還是實例方法.
如下例子演示了委托可以使用實例方法,也可以使用靜態方法:
Currency結構的聲明:
1 namespace Wrox.ProCSharp.Delegates { 2 struct Currency { 3 public uint Dollars; 4 public ushort Cents; 5 6 public Currency( uint dollars, ushort cents) { 7 this .Dollars = dollars; 8 this .Cents = cents; 9 } 10 11 public override string ToString() { 12 return string .Format( " ${0}.{1,-2:00} " , Dollars, Cents); 13 } 14 15 public static string GetCurrencyUnit() { 16 return " Dollar " ; 17 } 18 19 public static explicit operator Currency( float value) { 20 checked { 21 uint dollars = ( uint )value; 22 ushort cents = ( ushort )((value - dollars) * 100 ); 23 return new Currency(dollars, cents); 24 } 25 } 26 27 public static implicit operator float (Currency value) { 28 return value.Dollars + (value.Cents / 100.0f ); 29 } 30 31 public static implicit operator Currency( uint value) { 32 return new Currency(value, 0 ); 33 } 34 35 public static implicit operator uint (Currency value) { 36 return value.Dollars; 37 } 38 } 39 40 }
在住函數中調用:
1 using System; 2 3 namespace Wrox.ProCSharp.Delegates 4 { 5 class Program 6 { 7 private delegate string GetAString(); 8 9 static void Main() 10 { 11 int x = 40 ; 12 GetAString firstStringMethod = x.ToString; 13 Console.WriteLine( " String is {0} " , firstStringMethod()); 14 15 Currency balance = new Currency( 34 , 50 ); 16 17 // firstStringMethod references an instance method 18 firstStringMethod = balance.ToString; 19 Console.WriteLine( " String is {0} " , firstStringMethod()); 20 21 // firstStringMethod references a static method 22 firstStringMethod = new GetAString(Currency.GetCurrencyUnit); 23 Console.WriteLine( " String is {0} " , firstStringMethod()); 24 25 } 26 } 27 }
? 輸出:
String is 40 String is $ 34.50 String is Dollar
? 再來看一個委托使用:
定義操作的方法的類:
1 namespace SimpleDelegates_Demo { 2 class MathOperations { 3 public static double MultiplyByTwo( double value) { 4 return value * 2 ; 5 } 6 7 public static double Square( double value) { 8 return value * value; 9 } 10 } 11 12 }
在主函數中使用:
1 using System; 2 3 namespace SimpleDelegates_Demo { 4 delegate double Operate( double input); 5 class Program { 6 static void Main( string [] args) { 7 Operate[] actions = { MathOperations.MultiplyByTwo, MathOperations.Square }; 8 // 遍歷每個委托實例. 9 foreach (Operate action in actions) { 10 ProcessAndDisplayResult(action, 2 ); 11 ProcessAndDisplayResult(action, 2.5 ); 12 ProcessAndDisplayResult(action, 5.2 ); 13 Console.WriteLine(); 14 } 15 } 16 17 static void ProcessAndDisplayResult(Operate action, double inputVal) { 18 Console.WriteLine( " Input is [{0}],Result is [{1}] " , inputVal, action(inputVal)); 19 } 20 } 21 }
output:
1 Input is [ 2 ],Result is [ 4 ] 2 Input is [ 2.5 ],Result is [ 5 ] 3 Input is [ 5.2 ],Result is [ 10.4 ] 4 5 Input is [ 2 ],Result is [ 4 ] 6 Input is [ 2.5 ],Result is [ 6.25 ] 7 Input is [ 5.2 ],Result is [ 27.04 ]
在這個例子中,我們將委托實例封裝到一個數組中,然后遍歷每個委托實例,然后傳遞遍歷到特定的方法中調用,這說明使用委托的一種方式 - 即把方法組合到一個數組中來使用,這樣就可以在循環中調用不同的方法了.
值得注意的是,這里 ProcessAndDisplayResult(Operate action, double inputVal) 不是多余的.
當我們在主函數的第10~12行中傳遞action委托實例到 ProcessAndDisplayResult(Operate action, double inputVal) 方法的時候,
action就是
委托表示的方法.
而在ProcessAndDisplayResult(Operate action, double inputVal)方法體中,也就是上面Program類中的第18行中的action(inputVal),或action(2)實際上調用這個方法,參數放在圓括號中.也就是說, action(inputVal),或action(2) 實際上是調用action委托實例封裝的方法.
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
