您的位置:首页 > 编程语言 > C#

C#中的委托和事件

2010-03-19 09:43 218 查看
原文地址:http://www.dingos.cn/index.php?topic=875.0

【委托】
有时某个方法执行的操作不是针对数据进行的,而是对另一个方法进行操作;在编译时不知道第二个方法是什么,只能当运行时才知道,此时需要使用把第二个方法当成参数传递给第一个参数。当要把方法传递给参数时,需要委托。

委托常见应用:

C#中的事件模型。用它们指明处理给定事件的方法。通知代码发生了什么事件。

启动线程:多线程编程中使用委托来指定启动一个线程时调用的方法。在C#中,可以告诉计算机并行运行某些新的执行序列。

用于异步回调

通用库类:有许多库包含执行各种标准任务的代码。

【委托实现的步骤】

定义委托
public delegate void Del(string message);

实例化委托
Del handler = DelegateMethod;

使用委托
public static void DelegateMethod(string message) {
System.Console.WriteLine(message);
} // 为委托创建一个方法
handler("Hello World");

注意:

在运行时确定调用哪种方法

委托和方法必须具有相同的签名

using System;
public delegate string PDelegate(int i);
class Test{
public string Print(int i){
Console.WriteLine(i);
}
static void Main(){
Test t=new Test();
PDelegate pd=new PDelegate(t.Print);
pd(5);
}
}

【委托含义】
委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。 – C#编程指南。

【委托说明】

一个委托对象一次可以搭载多个方法,而不是一次一个。当我们使用一个搭载了多个方法的委托,所有方法以其“被搭载到委托对象的顺序”被依次使用。

一个委托对象所搭载的方法不需要属于同一个类。一个委托对象所搭载的所有方法必须具有相同的原型和形式。然而,这些方法可以既有静态也有非静态,可以有一个或多个类的成员组成。

委托是函数的封装,它代表一“类”函数。它们都符合一定的签名:拥有相同的参数列表、返回值类型。同时委托也可以看成是对函数的抽象,是函数的“类”。此时,委托的实例将代表一个具体的函数。

【多播委托】

委托也可以包含多个方法;这种委托称为多播委托。

如果调用多播委托,可以按顺序连续调用多个方法;此时委托的签名必须返回void。不能带输出参数(可以带引用参数)。多播委托应用于事件模型中。

若要向委托的方法列表(调用列表)中添加额外的方法,只需使用加法运算符或加法赋值运算符(“+”或“+=”)添加两个委托。

public class DelClass{
public void Method1(string message){}
public void Method2(string message){}
}

DelClass obj = new DelClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = obj.DelegateMethod;
Del allMethodsDelegate =d1 + d2; allMethodsDelegate += d3;

【委托的特点】

委托类似于 C++ 函数指针,但它是类型安全的。

委托允许将方法作为参数进行传递。

委托可用于定义回调方法。

委托可以链接在一起;

方法不需要与委托签名精确匹配。

【事件】
C#中的事件允许一个对象将发生的事件或修改通知其他对象,将发生的事件通知其他对象的对象称为发行者。对象可以订阅事件,该对象称为订阅者。一个事件可以有一个或多个订阅者,事件的发行者也可以是该事件的订阅者。

【创建和使用事件】

创建或标识一个委托。
public delegate void delegateMe();

创建一个类,包含:

定义事件:
[访问修饰符] event delegate类型 事件名;
private event delegateMe eventMe;

验证event声明的委托实例是否存在、调用此事件的方法
if(condition){ // 判断委托实例是否存在
eventMe(); // 调用订阅特定事件的对象的所有委托
}

订阅事件: 具有+=运算符和-=运算符将一个或多个方法与事件关联或者消除关联
eventMe += new delegateMe(objA.Method);
eventMe += new delegateMe(objB.Method);

使用此事件[触发事件]

using System;
//用于事件的委托一般都有两个参数:事件源,事件参数
delegate void MailHandler(object sender, string subject);
class MailManager{
//定义事件,它是某个委托的实例
public event MailHandler MailRive;
//通知注册客户,有新邮件到达
protected virtual void OnMailRive(string subject){
if(MailRive!=null) //确保客户已经注册了该事件
MailRive(this, subject);
}
//新邮件到达时,调用通知函数
public void ArriveMail(string subject){
OnMailRive(subject);
}
}

class Printer{
private MailManager mm;
public Printer(MailManager mm){
this.mm=mm;
this.mm.MailRive+=new MailHandler(OnMail); //注册
}
public void OnMail(object sender, string subject){
Console.WriteLine(“新邮件到达,主题为:”+subject);
}
}
class Test{
public static void Main(){
MailManager mm=new MailManager();
Printer print=new Printer(mm);
mm.ArriveMail(“hello”);
}
}

【事件编写的步骤】

创建委托,如果这个委托类型存在了,就可以不用定义。

定义一个事件源类

定义一个事件名

调用事件

触发事件,条件成立,调用事件执行

编写类实现事件

声明并实例化事件源类

添加事件:+= new 委托类型(事件处理函数名)

调用触发事件函数

编写事件处理函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: