首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 数据库 第二书店 程序员

C#编程语言详解(第2版) - 免费试读 - book.csdn.net


10.7 事件
事件(event)是一种使对象或类可以提供通知的成员。客户端可以通过提供事件处理程序(event handler)来为事件添加可执行代码。

事件使用事件声明来声明:

event-declaration:

attributesopt event-modifiersopt event type variable-declarators ;

attributesopt event-modifiersopt event type member-name { event- accessor-declarations }

event-modifiers:

event-modifier

event-modifiers event-modifier

event-modifier:

new

public

protected

internal

private

static

virtual

sealed

override

abstract

extern

event-accessor-declarations:

add-accessor-declaration remove-accessor-declaration

remove-accessor-declaration add-accessor-declaration

add-accessor-declaration:

attributesopt add block

remove-accessor-declaration:

attributesopt remove block

事件声明可以包含一组特性(参见第17章)和4个访问修饰符(参见10.2.3小节)的一个有效组合,还可以包含new(参见10.2.2小节)、static(参见10.5.2小节)、virtual(参见10.5.3小节)、override(参见10.5.4小节)、sealed(参见10.5.5小节)、abstract(参见10.5.6小节)以及extern(参见10.5.7小节)等修饰符。

对于有效的修饰符组合,事件声明与方法声明(参见10.5节)遵循相同的规则。

事件声明的类型必须是一个委托类型(参见4.2节),而该委托类型必须至少具有与事件本身相同的可访问性(参见3.5.4小节)。

事件声明中可以包含事件访问器声明。不过,如果声明中不包含事件访问器声明,对于非外部、非抽象的事件,编译器将自动为其提供事件访问器声明(参见10.7.1小节);而对于外部事件,访问器由外部提供。

省略了事件访问器声明的事件声明可以定义一个或多个事件——每个变量声明符定义一个事件。这样的事件声明中的特性和修饰符适用于所有由该事件声明所声明的成员。

如果一个事件声明既包含abstract修饰符又包含以括号分隔的事件访问器声明,则将发生编译时错误。

如果一个事件声明包含extern修饰符,则称该事件为外部事件(external event)。由于外部事件声明不提供任何实际的实现,所以在一个外部事件声明中既包含extern修饰符又包含事件访问器声明是错误的。

事件可以用作“+=”和“-=”运算符(参见7.13.3小节)的左边的操作数。这两个运算符分别用于向事件添加事件处理程序或从事件移除事件处理程序,而事件的访问修饰符控制着允许执行这类运算的上下文。

由于“+=”和“-=”运算符是仅有的允许在声明一个事件的类型外部对该事件进行的操作,所以,外部代码可以为一个事件添加和移除处理程序,但是不能以其他任何方式来获取或修改基础的事件处理程序列表。

在形式为“x += y”或“x -= y”的运算中,如果x是一个事件,并且该引用发生在包含x的声明的类型之外,则这类运算的结果将具有类型void(而不是在赋值之后具有x的类型和x的值)。此规则禁止了外部代码以间接方式检查事件的基础委托。

下面的示例显示了如何将事件处理程序添加到Button类的实例:

public delegate void EventHandler(object sender, EventArgs e);

public class Button: Control

{

public event EventHandler Click;

}

public class LoginDialog: Form

{

Button OkButton;

Button CancelButton;

public LoginDialog() {

OkButton = new Button(...);

OkButton.Click += new EventHandler(OkButtonClick);

CancelButton = new Button(...);

CancelButton.Click += new EventHandler(CancelButtonClick);

}

void OkButtonClick(object sender, EventArgs e) {

//处理OkButton.Click事件

}

void CancelButtonClick(object sender, EventArgs e) {

//处理CancelButton.Click事件

}

}

这里,LoginDialog的实例构造函数创建了两个Button实例,并为Click事件添加了事件处理程序。

10.7.1 类似域的事件
在包含事件声明的类或结构的程序文本内,某些事件可以像域一样使用。如果要以这样的方式使用事件,则事件不能是抽象的或外部的,并且不能显式地包含事件访问器声明。这样的事件可以在任何允许使用域的上下文中使用。该域包含一个委托(参见第15章),该委托引用已添加到相应事件的事件处理程序列表。如果尚未添加任何事件处理程序,则该域包含null。

在下面的示例中:

public delegate void EventHandler(object sender, EventArgs e);

public class Button: Control

{

public event EventHandler Click;

protected void OnClick(EventArgs e) {

if (Click != null) Click(this, e);

}

public void Reset() {

Click = null;

}

}

Click在Button类中用作一个域。如上面的示例所示,可以在委托调用表达式中对该域进行检查、修改和使用。Button类中的OnClick方法用于“引发”Click事件。“引发一个事件”的概念完全等效于“调用一个由该事件表示的委托”,因此,不存在用于引发事件的特殊语言构造。注意,在委托调用之前有一个检查,以确保该委托非空。

在Button类的声明外部,Click成员只能用在“+=”和“-=”运算符的左边,如下面的语句:

b.Click += new EventHandler(...);

会将一个委托追加到Click事件的调用列表,而下面的语句:

b.Click –= new EventHandler(...);

则将从Click事件的调用列表中移除一个委托。

当编译一个类似域的事件时,编译器将自动创建一个存储区来存放相关的委托,并为事件创建访问器以向该委托域中添加或移除事件处理程序。为了线程安全,添加或移除操作将在为实例事件的包含对象加锁(参见8.12节)的情况下进行,或者在为静态事件的类型对象(参见7.5.11小节)加锁的情况下进行。

因此,如下形式的实例事件声明:

class X

{

public event D Ev;

}

可以编译为与如下代码等效的语句:

class X

{

private D __Ev; //存放委托的域

public event D Ev {

add {

lock(this) { __Ev = __Ev + value; }

}

remove {

lock(this) { __Ev = __Ev - value; }

}

}

}

在类X中,对Ev的引用在编译时将改为对隐藏域_Ev的引用。名称“_Ev”是任意的;隐藏域可以具有任何名称或根本没有名称。

同样,如下形式的静态事件声明:

class X

{

public static event D Ev;

}

可以编译为与如下代码等效的语句:

class X {

private static D __Ev; //存放委托的域

public static event D Ev {

add {

lock(typeof(X)) { __Ev = __Ev + value; }

}

remove {

lock(typeof(X)) { __Ev = __Ev - value; }

}

}

}

10.7.2 事件访问器
事件声明通常会省略事件访问器声明,如前面的Button示例中所示。例如,当为每个事件设置一个域所造成的内存开销不可接受时,就会省略事件访问器声明。在这种情况下,可以在类中使用事件访问器声明,并采用专用机制来存储事件处理程序列表。

事件的事件访问器声明用于指定与添加和移除事件处理程序相关的可执行语句。

访问器声明由一个添加访问器声明(add-accessor-declaration)和一个移除访问器声明(remove-accessor-declaration)组成。每个访问器声明都由标记add或remove,后跟一个块组成。与添加访问器声明相关联的块用于指定添加一个事件处理程序时要执行的语句,而与移除访问器声明相关联的块则用于指定移除一个事件处理程序时要执行的语句。

每个添加访问器声明和移除访问器声明都相当于一个方法,这个方法具有一个事件类型的值参数,并且其返回类型为void。事件访问器的隐式参数名为value。当在事件赋值操作中使用事件时,将会调用适当的事件访问器。具体来讲,如果赋值运算符为“+=”,则使用添加访问器,而如果赋值运算符为“-=”,则使用移除访问器。在这两种情况下,赋值运算符的右操作数都用作事件访问器的自变量。添加访问器声明或移除访问器声明的块必须遵循10.5.8小节中所描述的void方法的规则。具体来讲,不允许此类块中的return语句指定表达式。

由于事件访问器隐式地具有一个名为value的参数,因此如果在事件访问器中声明的局部变量或常量具有该名称,将会发生编译时错误。

在下面的示例中:

class Control: Component

{

//事件的唯一的键

static readonly object mouseDownEventKey = new object();

static readonly object mouseUpEventKey = new object();

//返回与键相关联的事件处理程序

protected Delegate GetEventHandler(object key) {...}

//添加与键相关联的事件处理程序

protected void AddEventHandler(object key, Delegate handler) {...}

//移除与键相关联的事件处理程序

protected void RemoveEventHandler(object key, Delegate handler) {...}

//MouseDown事件

public event MouseEventHandler MouseDown {

add { AddEventHandler(mouseDownEventKey, value); }

remove { RemoveEventHandler(mouseDownEventKey, value); }

}

//MouseUp事件

public event MouseEventHandler MouseUp {

add { AddEventHandler(mouseUpEventKey, value); }

remove { RemoveEventHandler(mouseUpEventKey, value); }

}

//调用MouseUp

protected void OnMouseUp(MouseEventArgs args) {

MouseEventHandler handler;

handler = (MouseEventHandler)GetEventHandler(mouseUpEventKey);

if (handler != null)

handler(this, args);

}

}

Control类为事件实现了一种内部存储机制。AddEventHandler方法将一个委托值与一个键相关联,GetEventHandler方法返回当前与一个键相关联的委托,而RemoveEventHandler方法将移除一个委托,使它不再作为指定事件的事件处理程序。可以推断,在这样设计的基础存储机制下,当一个键所关联的委托值为null时,不会有存储开销,从而使未处理的事件不占用任何存储空间。

10.7.3 静态事件和实例事件
如果一个事件声明包含static修饰符,则称该事件为静态事件(static event)。如果不存在static修饰符,则称该事件为实例事件(instance event)。

静态事件不与特定实例相关联,在静态事件的访问器中引用this将导致编译时错误。

实例事件与类的给定实例相关联,在该事件的访问器中可以使用this(参见7.5.7小节)来访问此实例。

当在形式为E.M的成员访问(参见7.5.4小节)中引用事件时,如果M为静态事件,则E必须表示一个包含M的类型,而如果M为实例事件,则E必须表示包含M的类型的一个实例。

关于静态成员和实例成员之间差异的详细介绍,请参见10.2.5小节。

10.7.4 虚、密封、重写和抽象访问器
virtual事件声明用于指定事件的访问器是虚访问器。virtual修饰符将应用于事件的两个访问器。

abstract事件声明用于指定事件的访问器是虚访问器,但是并不提供访问器的实际实现。相反,非抽象的派生类需要通过重写事件来提供其自己的访问器实现。由于抽象事件声明的访问器不提供任何实际实现,所以它的访问器体只包含一个分号。

同时包含abstract和override修饰符的事件声明将指定该事件是抽象的,并重写一个基事件。此类事件的访问器也是抽象的。

抽象事件声明只允许在抽象类(参见10.1.1小节)中使用。

通过包含一个指定了override修饰符的事件声明,可以在派生类中重写继承的虚事件的访问器。这称为重写事件声明(overriding event declaration)。重写事件声明并不声明新事件。相反,它只是使现有虚事件的访问器的实现专用化。

重写事件声明必须采用与被重写事件完全相同的可访问性修饰符、类型和名称。

重写事件声明可以包含sealed修饰符。使用该修饰符可以防止派生类对该事件进行进一步的重写。密封事件的访问器也是密封的。

如果重写事件声明包含new修饰符,将会发生编译时错误。

除了声明和调用语法中的差异之外,虚、密封、重写和抽象访问器与虚、密封、重写和抽象方法具有完全相同的行为。具体来讲,10.5.3小节、10.5.4小节、10.5.5小节和10.5.6小节中所描述的规则都适用,就好像访问器是相应形式的方法一样。每个访问器都对应于一个方法,该方法具有单个该事件类型的值参数,返回类型为void,并且具有与该事件相同的修饰符。




他们设置了哪些标签:


3 C# C#编程语言 C#编程语言详解(第2版) VC 编程详解 编程语言 含有委托详解

谁收藏了这个网址:


cnim549405865收录

使用标签:C#编程语言详解(第2版), VC,时间:2007-11-30 18:11:54 | 相关网摘

C#是一种简单、现代、面向对象和类型安全的程序设计语言。本书由C#语言的架构师Anders Hejlsberg和设计小组的成员编写,并为C# 2.0进行了更新。全书从C#语言的简介开始,完整并详细地介绍了C# 1.0的技术规范,并介绍了许多C# 2.0的新功能,包括泛型、匿名方法、迭代器、分部类型和可空类型等。本书对第一版中介绍的C#新增了许多功能,并做了很多改进。\r\n 本书内容翔实,实例丰富,既可以作为高等院校学生学习C#的教材,也是希望深入探索C#编程知识的程序员的最权威的参考书。

wixsnow收录

时间:2007-12-14 10:29:44 | 相关网摘

dirkxxl收录

使用标签:C#,时间:2007-12-14 11:40:49 | 相关网摘

qiushy2007收录

时间:2007-12-14 13:48:03 | 相关网摘

foxflyhigher收录

使用标签:C#, 编程语言,时间:2007-12-14 15:37:47 | 相关网摘

学习C#编程语言的经典力著!!!

LonQi收录

时间:2007-12-14 17:26:32 | 相关网摘

huomm收录

时间:2007-12-14 18:43:31 | 相关网摘

ChailangCompany收录

时间:2007-12-14 20:07:25 | 相关网摘

yongguozhou收录

使用标签:含有委托详解,时间:2007-12-14 21:48:53 | 相关网摘

C#编程语言详

qingqumeng收录

时间:2007-12-14 22:41:07 | 相关网摘

ProgramerChina收录

使用标签:C#,时间:2007-12-14 22:46:33 | 相关网摘

zhangzhongping收录

时间:2007-12-15 9:04:56 | 相关网摘

KXF8537收录

时间:2007-12-15 9:28:26 | 相关网摘

happymugua收录

时间:2007-12-15 20:20:25 | 相关网摘

pc_cat收录

时间:2007-12-15 20:28:58 | 相关网摘

kangwei6430收录

时间:2007-12-15 23:22:52 | 相关网摘

john_czzj收录

时间:2007-12-16 10:41:39 | 相关网摘

LoneFOX23收录

时间:2007-12-16 11:54:17 | 相关网摘

netcellsoft收录

时间:2007-12-21 7:15:50 | 相关网摘

ldruth28收录

时间:2007-12-26 16:53:09 | 相关网摘

mysql_php收录

使用标签:c#,时间:2008-1-17 17:33:02 | 相关网摘

类,接口,枚举,委托

oeskf收录

时间:2008-1-21 20:08:57 | 相关网摘

ZZ505收录

时间:2008-2-6 0:13:17 | 相关网摘

HumamConder收录

时间:2008-2-17 0:43:53 | 相关网摘

ayajenson收录

时间:2008-2-29 10:13:07 | 相关网摘

书名:C#编程语言详解(第2版)

uncooperater收录

时间:2008-2-29 10:16:58 | 相关网摘

bell6收录

时间:2008-2-29 10:19:23 | 相关网摘

jjx5373收录

时间:2008-2-29 11:42:03 | 相关网摘

tzp_8收录

使用标签:C#编程语言详解(第2版),时间:2008-2-29 17:14:21 | 相关网摘

flash_avatar收录

时间:2008-2-29 17:59:59 | 相关网摘

型安全的程序设计语言。本书由C#语言的架构师Anders Hejlsberg和设计小组的成员编写,并为C# 2.0进行了更新。全书从C#语言的简介开始,完整并详细地介绍了C# 1.0的技术规范,并介绍了许多C# 2.0的新功能,包括泛型、匿名方法、迭代器、分部类型和可空类型等。本书对第一版中介绍的C#新增了许多功能,并做了很多改进。\r\n 本书内容翔实,实例丰富,既可以作为高等院校学生学习C#的教材,也是希望深入探索C#编程知识的

xiaowenmanbu收录

时间:2008-2-29 22:50:14 | 相关网摘

glorey收录

时间:2008-3-1 0:47:53 | 相关网摘

C#教程

xmucmd收录

使用标签:C#,时间:2008-3-1 3:10:44 | 相关网摘

haoyueliuxing收录

时间:2008-3-1 4:04:38 | 相关网摘

zhongwjx收录

时间:2008-3-1 12:17:40 | 相关网摘

10.7 事件
事件(event)是一种使对象或类可以提供通知的成员。客户端可以通过提供事件处理程序(event handler)来为事件添加可执行代码。

事件使用事件声明来声明:

event-declaration:

attributesopt event-modifiersopt event type variable-declarators ;

attributesopt event-modifiersopt event type member-name { event- accessor-declarations }

event-modifiers:

event-modifier

event-modifiers event-modifier

event-modifier:

new

public

protected

internal

private

static

virtual

sealed

override

abstract

extern

event-accessor-declarations:

add-accessor-declaration remove-accessor-declaration

remove-accessor-declaration add-accessor-declaration

add-accessor-declaration:

attributesopt add block

remove-accessor-declaration:

attributesopt remove block

事件声明可以包含一组特性(参见第17章)和4个访问修饰符(参见10.2.3小节)的一个有效组合,还可以包含new(参见10.2.2小节)、static(参见10.5.2小节)、virtual(参见10.5.3小节)、override(参见10.5.4小节)、sealed(参见10.5.5小节)、abstract(参见10.5.6小节)以及extern(参见10.5.7小节)等修饰符。

对于有效的修饰符组合,事件声明与方法声明(参见10.5节)遵循相同的规则。

事件声明的类型必须是一个委托类型(参见4.2节),而该委托类型必须至少具有与事件本身相同的可访问性(参见3.5.4小节)。

事件声明中可以包含事件访问器声明。不过,如果声明中不包含事件访问器声明,对于非外部、非抽象的事件,编译器将自动为其提供事件访问器声明(参见10.7.1小节);而对于外部事件,访问器由外部提供。

省略了事件访问器声明的事件声明可以定义一个或多个事件——每个变量声明符定义一个事件。这样的事件声明中的特性和修饰符适用于所有由该事件声明所声明的成员。

如果一个事件声明既包含abstract修饰符又包含以括号分隔的事件访问器声明,则将发生编译时错误。

如果一个事件声明包含extern修饰符,则称该事件为外部事件(external event)。由于外部事件声明不提供任何实际的实现,所以在一个外部事件声明中既包含extern修饰符又包含事件访问器声明是错误的。

事件可以用作“+=”和“-=”运算符(参见7.13.3小节)的左边的操作数。这两个运算符分别用于向事件添加事件处理程序或从事件移除事件处理程序,而事件的访问修饰符控制着允许执行这类运算的上下文。

由于“+=”和“-=”运算符是仅有的允许在声明一个事件的类型外部对该事件进行的操作,所以,外部代码可以为一个事件添加和移除处理程序,但是不能以其他任何方式来获取或修改基础的事件处理程序列表。

在形式为“x += y”或“x -= y”的运算中,如果x是一个事件,并且该引用发生在包含x的声明的类型之外,则这类运算的结果将具有类型void(而不是在赋值之后具有x的类型和x的值)。此规则禁止了外部代码以间接方式检查事件的基础委托。

下面的示例显示了如何将事件处理程序添加到Button类的实例:

public delegate void EventHandler(object sender, EventArgs e);

public class Button: Control

{

public event EventHandler Click;

}

public class LoginDialog: Form

{

Button OkButton;

Button CancelButton;

public LoginDialog() {

OkButton = new Button(...);

OkButton.Click += new EventHandler(OkButtonClick);

CancelButton = new Button(...);

CancelButton.Click += new EventHandler(CancelButtonClick);

}

void OkButtonClick(object sender, EventArgs e) {

//处理OkButton.Click事件

}

void CancelButtonClick(object sender, EventArgs e) {

//处理CancelButton.Click事件

}

}

这里,LoginDialog的实例构造函数创建了两个Button实例,并为Click事件添加了事件处理程序。

10.7.1 类似域的事件
在包含事件声明的类或结构的程序文本内,某些事件可以像域一样使用。如果要以这样的方式使用事件,则事件不能是抽象的或外部的,并且不能显式地包含事件访问器声明。这样的事件可以在任何允许使用域的上下文中使用。该域包含一个委托(参见第15章),该委托引用已添加到相应事件的事件处理程序列表。如果尚未添加任何事件处理程序,则该域包含null。

在下面的示例中:

public delegate void EventHandler(object sender, EventArgs e);

public class Button: Control

{

public event EventHandler Click;

protected void OnClick(EventArgs e) {

if (Click != null) Click(this, e);

}

public void Reset() {

Click = null;

}

}

Click在Button类中用作一个域。如上面的示例所示,可以在委托调用表达式中对该域进行检查、修改和使用。Button类中的OnClick方法用于“引发”Click事件。“引发一个事件”的概念完全等效于“调用一个由该事件表示的委托”,因此,不存在用于引发事件的特殊语言构造。注意,在委托调用之前有一个检查,以确保该委托非空。

在Button类的声明外部,Click成员只能用在“+=”和“-=”运算符的左边,如下面的语句:

b.Click += new EventHandler(...);

会将一个委托追加到Click事件的调用列表,而下面的语句:

b.Click –= new EventHandler(...);

则将从Click事件的调用列表中移除一个委托。

当编译一个类似域的事件时,编译器将自动创建一个存储区来存放相关的委托,并为事件创建访问器以向该委托域中添加或移除事件处理程序。为了线程安全,添加或移除操作将在为实例事件的包含对象加锁(参见8.12节)的情况下进行,或者在为静态事件的类型对象(参见7.5.11小节)加锁的情况下进行。

因此,如下形式的实例事件声明:

class X

{

public event D Ev;

}

可以编译为与如下代码等效的语句:

class X

{

private D __Ev; //存放委托的域

public event D Ev {

add {

lock(this) { __Ev = __Ev + value; }

}

remove {

lock(this) { __Ev = __Ev - value; }

}

}

}

在类X中,对Ev的引用在编译时将改为对隐藏域_Ev的引用。名称“_Ev”是任意的;隐藏域可以具有任何名称或根本没有名称。

同样,如下形式的静态事件声明:

class X

{

public static event D Ev;

}

可以编译为与如下代码等效的语句:

class X {

private static D __Ev; //存放委托的域

public static event D Ev {

add {

lock(typeof(X)) { __Ev = __Ev + value; }

}

remove {

lock(typeof(X)) { __Ev = __Ev - value; }

}

}

}

10.7.2 事件访问器
事件声明通常会省略事件访问器声明,如前面的Button示例中所示。例如,当为每个事件设置一个域所造成的内存开销不可接受时,就会省略事件访问器声明。在这种情况下,可以在类中使用事件访问器声明,并采用专用机制来存储事件处理程序列表。

事件的事件访问器声明用于指定与添加和移除事件处理程序相关的可执行语句。

访问器声明由一个添加访问器声明(add-accessor-declaration)和一个移除访问器声明(remove-accessor-declaration)组成。每个访问器声明都由标记add或remove,后跟一个块组成。与添加访问器声明相关联的块用于指定添加一个事件处理程序时要执行的语句,而与移除访问器声明相关联的块则用于指定移除一个事件处理程序时要执行的语句。

每个添加访问器声明和移除访问器声明都相当于一个方法,这个方法具有一个事件类型的值参数,并且其返回类型为void。事件访问器的隐式参数名为value。当在事件赋值操作中使用事件时,将会调用适当的事件访问器。具体来讲,如果赋值运算符为“+=”,则使用添加访问器,而如果赋值运算符为“-=”,则使用移除访问器。在这两种情况下,赋值运算符的右操作数都用作事件访问器的自变量。添加访问器声明或移除访问器声明的块必须遵循10.5.8小节中所描述的void方法的规则。具体来讲,不允许此类块中的return语句指定表达式。

由于事件访问器隐式地具有一个名为value的参数,因此如果在事件访问器中声明的局部变量或常量具有该名称,将会发生编译时错误。

在下面的示例中:

class Control: Component

{

//事件的唯一的键

static readonly object mouseDownEventKey = new object();

static readonly object mouseUpEventKey = new object();

//返回与键相关联的事件处理程序

protected Delegate GetEventHandler(object key) {...}

//添加与键相关联的事件处理程序

protected void AddEventHandler(object key, Delegate handler) {...}

//移除与键相关联的事件处理程序

protected void RemoveEventHandler(object key, Delegate handler) {...}

//MouseDown事件

public event MouseEventHandler MouseDown {

add { AddEventHandler(mouseDownEventKey, value); }

remove { RemoveEventHandler(mouseDownEventKey, value); }

}

//MouseUp事件

public event MouseEventHandler MouseUp {

add { AddEventHandler(mouseUpEventKey, value); }

remove { RemoveEventHandler(mouseUpEventKey, value); }

}

//调用MouseUp

protected void OnMouseUp(MouseEventArgs args) {

MouseEventHandler handler;

handler = (MouseEventHandler)GetEventHandler(mouseUpEventKey);

if (handler != null)

handler(this, args);

}

}

Control类为事件实现了一种内部存储机制。AddEventHandler方法将一个委托值与一个键相关联,GetEventHandler方法返回当前与一个键相关联的委托,而RemoveEventHandler方法将移除一个委托,使它不再作为指定事件的事件处理程序。可以推断,在这样设计的基础存储机制下,当一个键所关联的委托值为null时,不会有存储开销,从而使未处理的事件不占用任何存储空间。

10.7.3 静态事件和实例事件
如果一个事件声明包含static修饰符,则称该事件为静态事件(static event)。如果不存在static修饰符,则称该事件为实例事件(instance event)。

静态事件不与特定实例相关联,在静态事件的访问器中引用this将导致编译时错误。

实例事件与类的给定实例相关联,在该事件的访问器中可以使用this(参见7.5.7小节)来访问此实例。

当在形式为E.M的成员访问(参见7.5.4小节)中引用事件时,如果M为静态事件,则E必须表示一个包含M的类型,而如果M为实例事件,则E必须表示包含M的类型的一个实例。

关于静态成员和实例成员之间差异的详细介绍,请参见10.2.5小节。

10.7.4 虚、密封、重写和抽象访问器
virtual事件声明用于指定事件的访问器是虚访问器。virtual修饰符将应用于事件的两个访问器。

abstract事件声明用于指定事件的访问器是虚访问器,但是并不提供访问器的实际实现。相反,非抽象的派生类需要通过重写事件来提供其自己的访问器实现。由于抽象事件声明的访问器不提供任何实际实现,所以它的访问器体只包含一个分号。

同时包含abstract和override修饰符的事件声明将指定该事件是抽象的,并重写一个基事件。此类事件的访问器也是抽象的。

抽象事件声明只允许在抽象类(参见10.1.1小节)中使用。

通过包含一个指定了override修饰符的事件声明,可以在派生类中重写继承的虚事件的访问器。这称为重写事件声明(overriding event declaration)。重写事件声明并不声明新事件。相反,它只是使现有虚事件的访问器的实现专用化。

重写事件声明必须采用与被重写事件完全相同的可访问性修饰符、类型和名称。

重写事件声明可以包含sealed修饰符。使用该修饰符可以防止派生类对该事件进行进一步的重写。密封事件的访问器也是密封的。

如果重写事件声明包含new修饰符,将会发生编译时错误。

除了声明和调用语法中的差异之外,虚、密封、重写和抽象访问器与虚、密封、重写和抽象方法具有完全相同的行为。具体来讲,10.5.3小节、10.5.4小节、10.5.5小节和10.5.6小节中所描述的规则都适用,就好像访问器是相应形式的方法一样。每个访问器都对应于一个方法,该方法具有单个该事件类型的值参数,返回类型为void,并且具有与该事件相同的修饰符。

MKL11收录

时间:2008-3-1 13:36:15 | 相关网摘

dqssimon收录

使用标签:C#,时间:2008-3-1 19:42:28 | 相关网摘

Yanzzz收录

时间:2008-3-2 0:08:14 | 相关网摘

yqowen收录

使用标签:c#, 编程详解,时间:2008-3-2 1:03:21 | 相关网摘

hlzyy收录

时间:2008-3-2 12:25:44 | 相关网摘

beijixue2005收录

使用标签:C#编程语言详解(第2版),时间:2008-3-3 8:48:23 | 相关网摘

C#编程语言详解(第2版)

fengi2208收录

时间:2008-3-3 9:00:36 | 相关网摘

mthyx收录

时间:2008-3-4 18:43:32 | 相关网摘

liudaax收录

使用标签:3,时间:2008-3-15 20:00:34 | 相关网摘


网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
Copyright © 2000-2008, CSDN.NET, All Rights Reserved