荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: sephiroth (bird of paradise), 信区: DotNET
标  题: 如何使用.NET中的集合
发信站: 荔园晨风BBS站 (Thu Sep 19 12:21:09 2002), 站内信件


问:我是一名程序员,使用VB很久了,现在正在钻研.NET。我实在是弄不清它的集
合类型:我找不到它和VB6的集合相对应的部分。.NET上有相应的集合吗?


答:集合类型是VB6程序员最好的朋友:它的确是把多组对象集中入一个组的唯一
方法,并能提供无争辩的枚举。它使得从组内检索任意对象变得很容易。我还可以
先告诉你,在.NET里没有和VB6集合相对应的部分。你现在所能拥有的其实是很多
类似于VB6集合的一揽子替换方案。事实上,在你寻找.NET的集合时,你要问自己
的第一个问题是,“我真的需要一个吗”?

试试如下的数组吧:
要记住,所有的.NET语言都能够创建对象类型的数组。一般而言,数组在访问速度
和内存利用率上要比任何集合的效率都高,而且在许多情况使用数组就足够了。实
际上,很多.NET框架的一般集合类是由Object数组支持的。

假如你有一个类:Person,在VB.NET里,你会使用以下代码创建一个包含10项内容
的Person数组:

Dim Persons(10) As Person

在C#里,会是这样:

Person[] persons = new Person[10];

如我所述,绝大多数情况下,数组优于集合,唯一的例外是只有当:

对象数量的增加或减少无法预计时。
需要存储的数据不都是同一类型时。
需要对从数组加入或者检索的对象进行操作时。
所以你真的需要集合吗?
如果你已经决定了肯定要使用集合,那么你就要决定哪种集合最合适:集合、形式
表或者字典。简而言之,这些集合类型可以被细分为如下几种:

集合只是一组有序的对象,这些对象只能通过排序枚举来检索。到System.
Collections.ICollection接口查询集合的正式定义。
形式表,相反,允许直接索引到低层的集合,它同时也支持枚举。形式表由
System.Collections.ILis接口定义。
字典,就像形式表一样,既允许枚举也允许直接索引到集合,但是会存储每个对象
及其相关键值,并用键值给对象进行排序。需要了解更多信息可以看System.
Collections.IDictionary。

------------------------------------------------------------------------
--------

另一个最好的东西

.NET里和VB6 Collection最接近的是字典。唯一的不同是,它不像VB版本里的那样
容易通过数值索引。要获得相同的功能,你需要创建一个能执行IList和
IDictionary的类。


------------------------------------------------------------------------
--------

.NET Framework为每种类型的集合提供了许多标准执行。对于任何情况你都可能会
找适用的。假如需要一些帮助来区分它们并选择正确的一个,查一查《认识.Net集
合》 如果找不到合适的集合,你总可以选择使用适当的接口来创建自己的集合。
在VB.NET的源文件里查找由我创建的形式表WidgeList,并在Listing A看看它是如
何被创建的。要注意的是在执IList的同时,WidgetList事实上也就执行了
ICollection。

关于WidgetList很爽的就是,执行IList的本意就是为所有的目的服务的,从集合
甚至是到.NET的实时处理。它可以在任何普通形式表集合能用的地方与之互换使用
,这一点与VB6里的自定义集合不同,后者与VB6 Collection的类型不兼容。


------------------------------------------------------------------------
--------
关于执行的几句话

一个接口可以看作是你的对象和其他它需要调用的对象之间的协议,这也就是说,
如果你要执行一个接口的某种方法,你就必须要实现所有的方法。至少,你应该给
你不用执行的任何方法标上NotSupportedException。而且,微软的文档清楚地指
明在特定环境下,特定的接口方法要被标上例外。你也应该遵守这些指导方针,因
为其它的程序员或许会使用到你的类里特定的例外。


------------------------------------------------------------------------
--------

使用IEnumerable来虚拟实现
无可否认的是,通过实现某一集合接口来创建集合的工作量不小。幸运的是,有个
捷径。你会注意到我在Listing A中的WidgetList类不仅执行了Ilist,还同时执行
了第二个接口:IEnumerator。IEnumerator定义了用于.NET中用以迭代集合的方法
。更确切的说,当然你使用一个for…each结构来迭代集合时。

Listing A—The WidgetList and Widget classes


Imports System.Collections
Module VBNetCollection

    Sub Main()
        Dim wl As New WidgetList(5)
        Dim w As Widget
        Dim i As Integer

        System.Console.WriteLine("Adding 2 widgets...")

IEnumerator只包含三种方法:

Current返回的是集合中的当前项目
MoveNext将“当前”指针移到集合中的下一个项目。如果指针处于集合的合法位置
,则返回真值;如果指针已经到了集合的末尾,则返回的是伪值。
Reset将“当前”指针移到集合第一个项目之前,这样MoveNext会把第一个项目作
为当前项目。
这里的把戏是任何执行IEnumberable的类可以被一个集合迭代,即使它并不执行我
们先前谈及的任何集合接口。所以任何有执行功能的类都能提供类似于集合的枚举
(这是使用集合的巨大优点之一),即使它并不是真正的集合。

如果说.NET集合的接口有缺点的话,那么就是加入到它们中的任何东西的类型都成
了Object。这对作为程序员的你意味着:当你检索它们的时候你必须把它们恢复成
原来的类型。而值的类型(例如整数型)必须被框起来(转变成参考类型)。这两
点对性能的影响不大,同时这也是为什么你应该仔细考虑是否该使用数组的另一个
原因,尤其是在对性能敏感的环境下。

※ 来源:·荔园晨风BBS站 bbs.szu.edu.cn·[FROM: 192.168.44.81]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店