VFP8中使用集合
原名: Collections are Cool! 作者: Doug Hennig 译文: s_tiger
资料来源:code-magazine 网址: code-magazine/focus/Article.aspx?quickid=0301042
集合是存贮某些事物多个实例的
常用的方法。例如,树形控件具有结点的集合,微软的Word 具有
文档的集合。直到最近,VFP开发者想要用到集合,通常必须创建他们自己的类,而这也 只能是通过对数组复杂包装来实现。然而,除了需要编写更多的代码之外,自制的集合不支持 FOR EACH语句,尤其是在COM服务器中使用时更加的笨拙。Visual FoxPro 8.0 通过 提供真正的集合类解决了这个问题。
集合类只有很少的几个属性、事件和方法。Add方法用来向集合中添加条目,Remove方法用 来删除一个条目,Item方法返回一个条目,Count属性显示集合中共有多少条目。 一个 “条目” 可以有不同的数值类型比如文本或数字,但通常会是一个对象。除了条目本身外,集合可以为每 个条目存一个关键字,比如名称。集合中的条目可以通过两种方式被确定: 位置:Collection.Item(2)从集合中返回第2个条目 关键字:Collection.Item('Doug') 返回以"Doug" 做关键字的条目。 因为Item方法是默认的方法,如果你愿意可以忽略它;Collection.Item(2)和Collection(2) 效果完全一样。 集合可以做为数组的简单替代品。集合中的每一个条目非常类似于数组中的每一个元素。然而, 因为它们是对象,所以集合比数组有更多的用途。本文将从三个特殊的用途谈一下集合的使用。
使用集合替代数组
某些对象需要存贮一些事物的集合。 举例来说, 一个表单管理器需要知道程序中每一个打开的表 单的信息。 除了通过使用一个对象引用表单之外, 它可能还需要知道表单中使用了哪些工具栏 (这 样你就可以避免对同一个工具栏的产生多个实例),表单是否加入了窗口菜单(MDI界面中用 来排列窗口及拆分窗口的菜单条目,译者注),该表单实例的数目(当同一个表单打开不止一次 时),等等。直到VFP8前,这些信息经常保存在数组中,每一行存一个表单,每一列存一个属 性。 然而, 当列的数目增加时, 想知道数组中保存了哪些信息以及信息在什么地方将变得越来越困难, 是第四列还是第七列保存了实例的数目?同样,因为VFP数组中不能有0行(空数组),当表 单关闭,从数组中移除条目的时候,你必须特别小心。 lnForms = alen(This.aForms, 1)?1
lnCols = alen(This.aForms, 2)
if lnForms = 0 This.aForms = .NULL. else * lnForm 是被关闭的表单的行号 adel(This.aForms, lnForm) dimension This.aForms[lnForms, lnCols] endif 当你使用集合时这种复杂的情况就消失了。 在集合中用一个对象代表一个表单, 而数组中使用一 个行来实现。该对象包含了对表单的引用,以及其它需要的信息。你更愿意写(或者读,出于以 上原因)哪种代码来获得一个表单的实例呢? * 基于数组的代码 lnPos = ascan(This.aForms, 'CustomerForm') lnRow = asubscript(This.aForms, lnPos, 1) lnInstance = This.aForms[lnRow, 4] * 基于集合的代码 lnInstance = ; This.oForms('CustomerForm').nInstance 从集合中移除一个对象是很easy的,因为不需要考虑数组的维度
问题这里。只需要调用集合的 Remove方法就够了。
把集合做为参数
设想一下,你想要调用一段程序填充某个对象中的一个数组。这不象肾结石,没有什么比传递一 个成员数组更难的了。 因为数组必须通过使用@操作符来引用, 但你不能对一个成员数组使用@ 操作符,你不得不先传递到局部数组,再用ACOPY()把局部数组传递到成员数组中,然而,为 了避免出错,你必须先准确定义好成员数组。在不同的
程序中,我有很多代码和下面的相似: dimension laItems[1] SomeFunction(@laItems) lnRows = alen(l