引言:
在我看来委托一直是一种比较特别的类型,刚开始学的时候总是朦朦胧胧的不知所云。有必要从头来过,记个笔记。该篇从委托的定义,委托的优点,如何理解委托以及委托的协变和逆变 依次展开。
目录:
一、 委托的定义:... 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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。