您好,登錄后才能下訂單哦!
引言:
在我看來委托一直是一種比較特別的類型,剛開始學的時候總是朦朦朧朧的不知所云。有必要從頭來過,記個筆記。該篇從委托的定義,委托的優點,如何理解委托以及委托的協變和逆變 依次展開。
目錄:
一、 委托的定義:... 1
二、 委托的優點:... 1
三、 如何理解委托:... 1
四、 委托中的協變與逆變:... 3
五、 總結。... 5
六、 參考:... 5
一、 委托的定義:
委托是一種定義方法簽名的類型,可以與具有兼容簽名的任何方法關聯。(這里的簽名包含返回值)
二、 委托的優點:
1) 委托類似于 C++ 函數指針,但它們是類型安全的。
2) 委托允許將方法作為參數進行傳遞。
3) 委托可用于定義回調方法。
4) 委托可以鏈接在一起;例如,可以對一個事件調用多個方法。
5) 方法不必與委托簽名完全匹配。(C#4.0)
6) C# 2.0 引入的 匿名方法 和C# 3.0引入的 Lambda 表達式都可編譯為委托類型,此類方法允許將代碼塊作為參數傳遞,以代替單獨定義的方法。
三、 如何理解委托:
有如委托的字面理解:將自己的事務囑托他人代為處理 ,delegate個人理解是 代理方法執行方法的內容。
組合多路廣播委托:+ 運算符將它們分配給一個要成為多路廣播委托的委托實例。- 運算符可用來從組合的委托移除組件委托。只有相同類型的委托才可以組合。
委托綜合示例:
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: //定義回調方法
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方法實例化委托,將方法作為參數進行傳遞
39: Del handler = new Del(DelegateMethod);
40: handler("向大家問個好吧。");
41: MethodWithCallback("大家好!", handler);
42:
43: //匿名方法來實例化委托
44: Del anotherhandler = DelegateMethod;
45: anotherhandler("Hello World");
46: MethodWithCallback("I am coming!", anotherhandler);
47:
48: //“Lambda 表達式”是一個匿名函數,可以其表達式分配給委托類型
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: }
四、 委托中的協變與逆變:
聽起來非常拗口,這里有一段出自msdn的權威解釋:
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(參數列表類型) <= 返回類型 被代理的方法(參數列表類型)
協變是方法的參數類型或返回類型的多繼承類型向代理聲明的參數類型或返回類型的相對較少的基類型轉換。
簡記為:
Delegate <= more derived types
逆變剛好相反,為基類型向繼承類型轉換。
Delegate <= less derived types
案例解析:
協變例子:
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: }
五、 總結。
委托最重要的概念是多路組合委托,最難理解的是委托的協變和逆變。
六、 參考:
委托中的協變和逆變
http://msdn.microsoft.com/zh-cn/library/ms173174(v=vs.90).aspx
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。