溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C#語言知識點(diǎn)整理 - 委托

發(fā)布時間:2020-06-23 16:05:48 來源:網(wǎng)絡(luò) 閱讀:538 作者:勇闖天涯X 欄目:編程語言

引言:

    在我看來委托一直是一種比較特別的類型,剛開始學(xué)的時候總是朦朦朧朧的不知所云。有必要從頭來過,記個筆記。該篇從委托的定義,委托的優(yōu)點(diǎn),如何理解委托以及委托的協(xié)變和逆變 依次展開。

目錄:

一、 委托的定義:... 1

二、 委托的優(yōu)點(diǎn):... 1

三、 如何理解委托:... 1

四、 委托中的協(xié)變與逆變:... 3

五、 總結(jié)。... 5

六、 參考:... 5

一、 委托的定義:

    委托是一種定義方法簽名的類型,可以與具有兼容簽名的任何方法關(guān)聯(lián)。(這里的簽名包含返回值)

二、 委托的優(yōu)點(diǎn):

1) 委托類似于 C++ 函數(shù)指針,但它們是類型安全的。

2) 委托允許將方法作為參數(shù)進(jìn)行傳遞。

3) 委托可用于定義回調(diào)方法。

4) 委托可以鏈接在一起;例如,可以對一個事件調(diào)用多個方法。

5) 方法不必與委托簽名完全匹配。(C#4.0)

6) C# 2.0 引入的 匿名方法 和C# 3.0引入的 Lambda 表達(dá)式都可編譯為委托類型,此類方法允許將代碼塊作為參數(shù)傳遞,以代替單獨(dú)定義的方法。

三、 如何理解委托:

    有如委托的字面理解:將自己的事務(wù)囑托他人代為處理 ,delegate個人理解是 代理方法執(zhí)行方法的內(nèi)容。

    組合多路廣播委托:+ 運(yùn)算符將它們分配給一個要成為多路廣播委托的委托實(shí)例。- 運(yùn)算符可用來從組合的委托移除組件委托。只有相同類型的委托才可以組合。

 

委托綜合示例:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5:  
   6: namespace CSharp.Delegate
   7: {
   8:     //聲明委托
   9:     public delegate void Del(string message);
  10:  
  11:     class Program
  12:     {
  13:         // Create a method for a delegate.
  14:         public static void DelegateMethod(string message)
  15:         {
  16:             System.Console.WriteLine(message);
  17:         }
  18:  
  19:         //定義回調(diào)方法
  20:         public static void MethodWithCallback(string message, Del callback)
  21:         {
  22:             callback(message);
  23:         }
  24:  
  25:         public static void Hello(string s)
  26:         {
  27:             System.Console.WriteLine("  Hello, {0}!", s);
  28:         }
  29:  
  30:         public static void Goodbye(string s)
  31:         {
  32:             System.Console.WriteLine("  Goodbye, {0}!", s);
  33:         }
  34:  
  35:         static void Main(string[] args)
  36:         {
  37:  
  38:             //new方法實(shí)例化委托,將方法作為參數(shù)進(jìn)行傳遞
  39:             Del handler = new Del(DelegateMethod);
  40:             handler("向大家問個好吧。");
  41:             MethodWithCallback("大家好!", handler);
  42:  
  43:             //匿名方法來實(shí)例化委托 
  44:             Del anotherhandler = DelegateMethod;
  45:             anotherhandler("Hello World");
  46:             MethodWithCallback("I am coming!", anotherhandler);
  47:  
  48:             //“Lambda 表達(dá)式”是一個匿名函數(shù),可以其表達(dá)式分配給委托類型
  49:             Del lamDel = (string s) =>
  50:             {
  51:                 Console.WriteLine(s);
  52:             };
  53:             lamDel("我是Lambda匿名委托!");
  54:  
  55:             //
  56:             //多路組合委托
  57:             //
  58:             //Hello,Goodbye,DelegateMethod 組合委托到d
  59:             Del d;
  60:             d = Hello;
  61:             d += Goodbye;
  62:             d += new Del(DelegateMethod);
  63:  
  64:             d("David");
  65:  
  66:             //移除委托DelegateMethod
  67:             d -= DelegateMethod;
  68:             d("David");
  69:  
  70:         }
  71:     }
  72: }

 

四、 委托中的協(xié)變與逆變:

    聽起來非常拗口,這里有一段出自msdn的權(quán)威解釋:

    Covariance and contravariance support for method groups allows for matching method signatures with delegate types. This enables you to assign to delegates not only methods that have matching signatures, but also methods that return more derived types (covariance) or that accept parameters that have less derived types (contravariance) than that specified by the delegate type.

 

以下是我個人的理解:

原型:

返回類型 Delegate(參數(shù)列表類型) <= 返回類型 被代理的方法(參數(shù)列表類型) 

協(xié)變是方法的參數(shù)類型或返回類型的多繼承類型向代理聲明的參數(shù)類型或返回類型的相對較少的基類型轉(zhuǎn)換。

簡記為:

Delegate <= more derived types 

逆變剛好相反,為基類型向繼承類型轉(zhuǎn)換。

Delegate <= less derived types 

案例解析:

協(xié)變例子:

   1: class Mammals
   2: {
   3: }
   4:  
   5: class Dogs : Mammals
   6: {
   7: }
   8:  
   9: class Program
  10: {
  11:     // Define the delegate.
  12:     public delegate Mammals HandlerMethod();
  13:  
  14:     public static Mammals FirstHandler()
  15:     {
  16:         return null;
  17:     }
  18:  
  19:     public static Dogs SecondHandler()
  20:     {
  21:         return null;
  22:     }
  23:  
  24:     static void Main()
  25:     {
  26:         HandlerMethod handler1 = FirstHandler;
  27:  
  28:         // Covariance allows this delegate.
  29:         //    Mammals() <= Dogs ()  
  30:         //   Dogs  more drived types than Mammals
  31:         HandlerMethod handler2 = SecondHandler;
  32:  
  33:     }
  34: }
  35:  

逆變例子:

   1: System.DateTime lastActivity;
   2: public Form1()
   3: {
   4:     InitializeComponent();
   5:  
   6: lastActivity = new System.DateTime();
   7: // KeyEventArgs <= System.EventArgs
   8: // MouseEventArgs <= System.EventArgs
   9: // System.EventArgs is less drived type than KeyEventArgs and
  10: // MouseEventArgs
  11:     this.textBox1.KeyDown += this.MultiHandler; //works with KeyEventArgs
  12: this.button1.MouseClick += this.MultiHandler; //works with MouseEventArgs
  13:  
  14: }
  15:  
  16: // Event hander for any event with an EventArgs or
  17: // derived class in the second parameter
  18: private void MultiHandler(object sender, System.EventArgs e)
  19: {
  20:     lastActivity = System.DateTime.Now;
  21: }

 

五、 總結(jié)。

    委托最重要的概念是多路組合委托,最難理解的是委托的協(xié)變和逆變。

六、 參考:

    委托中的協(xié)變和逆變

    http://msdn.microsoft.com/zh-cn/library/ms173174(v=vs.90).aspx

附件:http://down.51cto.com/data/2362511
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI