CH17 委托 .net复习课

来源:互联网 发布:织梦cms视频教程下载 编辑:程序博客网 时间:2024/05/01 13:50

.net通过委托来提供回调函数机制。
委托可以确保回调方法是类型安全的。

17.1认识委托
- 在非托管的C/C++中,函数的地址就是一个内存地址。不携带任何关于函数的其他信息,所以不是类型安全的。
- 可以在类中使用如下代码来定义委托
public delegate void Feedback(Object value, int item, int numItems);
- 使用委托
public void ProcessItem(Feedback feedback) //委托类型被以参数的形式传递给了ProcessItem函数
{
    //...some code
    if(feedback!=null)
        feedback(items[item], item, items.Length);
}

- 定义Callback函数,回调函数必须使用和Feedback的函数一致的签名(参数列表和返回值类型)
static void FeedbackToConsole(Object value, int item, it numItems);

17.2 使用委托回调静态方法
someInstance.ProcessItem(new Set.Feedback(App.FeedbackToConsole)); // App.FeedbackToConsole就是对静态方法的调用。
- 类型安全:编译器会确保App的FeedbackToConsole方法和FeedbackToMsgBox方法的原型与Feedback委托定义的原型完全相同。

17.3 使用委托回调实例方法
App appobj = new App();
someInstance.ProcessItems(new Set.Feedback(appobj.FeedbackToFile));
- 需要知道方法将要操作的实例对象

17.4 委托揭秘
- 首先看看委托是怎么构造的
- 我们在定义委托时,编译器实际会生成一个委托类
- 所有的委托都继承自System.MulticastDelegate类,其中的几个重要的私有字段
    - _target:应该被操作的对象
    - _methodPtr:内部指针,CLR用来表示回调方法
    - _prev:委托链上的前一个委托对象
- 在构造一个委托时,编译器将被操作对象的引用传给_target字段,而将回调方法的指针(由MethodDef或MethodRef元数据获得)传给_methodPtr。
- MutlicastDelegate还提过了Target(指向被操作对象)和Method(回调方法)两个公有属性。
d.Target.GetType(); //MulticastDelegate d;
d.Method.Name;

再来看看回调方法是如何被调用的
- 编译器遇到如下代码时:
feedback(items[item], item, items.Length);
将调用产生代码来调用委托对象的Invoke方法。
feedback.Invoke(items[item], item, items.Length);
- 注意:C#编译器不允许我们显示的调用Invoke方法。

17.6 委托判等
- 如果委托链中所有委托类型都相当,而且链的长度相等,那么两个委托相等。

17.7 委托链
- 利用MulticastDelegate的_prev指针来形成一个链表。
- 提供的静态方法:Combine(), Remove()
- 在尾部新添加委托
- 链表上的回调函数是递归调用,所以从链表的尾部开始调用。
* 委托对象一旦被创建,它们就被认为是恒定不变的。当我们用Combine或Remove来操作委托链时,新的委托对象被创建。

17.8 C#对委托链的支持
- 重载了+= 和-=两个操作符

原创粉丝点击