购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.4 事件和索引指示器

事件为类和类的实例提供了向外界发送通知的能力,而索引指示器则可以像数组那样对对象进行索引访问。在C和C++中没有事件和索引指示器的概念,它们是在C#中首次提出的。

2.4.1 事件

形象地说,事件(event)就是类或对象用来发出通知的成员,通过提供事件的句柄,客户能够把事件和可执行代码联系在一起。让我们一起先来看一个事件的例子,如果熟悉MFC的话理解这个例子应该不会很难。

程序清单 2-22:

在这个例子中,Click是类Button的一个域,可以获得它的值并进行修改,OnClick方法用于触发Click事件。

2.4.1.1 事件的声明

事件的声明格式:

事件的修饰符event-modifier可以是new、public、protected、internal、private、static、virtual、sealed、override、abstract。

static、virtual、override和abstract修饰符同一时刻只能出现在一个事件的声明中,可以包含事件访问说明或者依靠编译器自动提供一个访问器,它也可以省略事件访问说明,一次定义一个或多个事件。上面的例子中就省略了这个说明。

注意:使用了abstract修饰符的抽象事件必须省略事件访问说明,否则编译器会提示错误。

事件所声明的类型必须是一个代表(delegate)类型,代表类型应预先声明,如上例中的public delegate void EventHandler。

2.4.1.2 事件的预订和撤销

在下面的例子中,声明了一个使用Button类的登录对话框类,对话框类含有两个按钮:OK和Cancel按钮。

程序清单 2-23:

在例子中使用了Button类的两个实例,事件的预订是通过为事件加上左操作符+=来实现的,即

这样只要事件被触发,方法就会被调用。事件的撤销则采用左操作符-=来实现,即

如果在类中声明了事件,又希望像使用域那样使用事件,那么这个事件就不能是抽象的,也不能显式地包含事件。访问声明满足了这两个条件后,在任何可以使用域的场合都同样可以使用事件。

注意:对事件的触发相当于调用事件所表示的原型delegate,所以对delegate型原型的调用必须先经过检查,确保delegate不是null型的。

2.4.1.3 事件访问器

如Button的例子所示,大多数情况下,事件的声明都省略了事件访问。声明什么情况下使用事件访问声明呢?答案是如果每个事件的存储开销太大,就可以在类中包含事件访问声明,按私有成员的规则存放事件句柄列表。

访问器的声明包括添加访问器声明add-accessor-declaration和删除访问器声明remove-accessor-declaration。访问器声明之后跟随相关执行代码的语句块,在添加访问器声明后的代码需要执行添加事件句柄的操作;在删除访问器声明后的代码需要执行删除事件句柄的操作。不管是哪种事件访问器,都对应相应的一个方法,这个方法只有一个事件类型的值参数并且返回值为void。

在执行预订操作时,使用添加型访问器;在执行撤销操作时,使用删除型访问器。访问器中实际上还包含了一个名为value的隐藏参数,因而访问器在使用局部变量时不能再使用这个名字。

下面给出使用访问器的例子:

程序清单 2-24:

2.4.1.4 静态事件

和域方法等一样,在声明中使用了修饰符的事件称为静态事件。静态事件不与具体的实例相关联,因此不能在静态事件的访问器中引用this关键字,此外在静态事件声明时又加上virtual、abstract或override修饰符也都是不合法的,而对于非静态的事件可以在事件的访问器中使用this来指代类的实例。

2.4.2 索引指示器

索引指示器indexer使得可以像数组那样对对象使用下标,它提供了通过索引方式方便地访问类的数据信息的方法。

1.声明

索引指示器的声明格式:

索引指示器可以使用的修饰符indexer-modifier有new、public、protected、internal、private、virtual、sealed、override、abstract。

一对大括号{}之间是索引指示器的访问声明,使用get关键字和set关键字定义了对被索引的元素的读写权限。

例如,下面的例子用于打印出小组人员的名单:

程序清单 2-25:

在许多情况下,某些数据信息应该是属于类或类的实例所私有的,需要限制对这些信息的访问,而有时又不希望这类数据对外界完全封闭,和属性一样,索引指示器为我们提供了控制访问权限的另一种办法。

2.实例

本实例给出运用索引指示器的一个简单例子,例子是一个网络应用程序,根据域名解析IP地址:

程序清单 2-26:

程序的几点说明:

1)使用System.Net名字空间中的DNS类可以解析主机名,DNS类中提供了一个静态方法GetHostByName,这个方法返回一个IPHostEntry的对象,这个对象中含有IP地址列表。在编译该程序时,必须在编译器中声明包含System.Net名字空间:

2)有关csc的编译参数可以使用csc/?来浏览。 dUIqnUee+Ksa/e7ugOaziCeU1U1SeqSqyQkNdGX9p3NiykRo1kZ9BZ8DwCwaSUTe

点击中间区域
呼出菜单
上一章
目录
下一章
×