
公告 |
四川理工学院信息管理与信息系统专业学生,男,83年5月生。
职业:自由开发者
为人座右铭:做人要厚道
QQ:61951565
VFP群:4001858(已满员),17966472
E-mail:lugreen@163.com
QQ空间:Greeeeeeeeeeeeeen
本博客文章未经作者同意不得转载 |
Blog信息 |
blog名称:Green1Vfp 原创空间 日志总数:35 评论数量:101 留言数量:3 访问次数:443409 建立时间:2004年12月7日 |

| |
[高级技巧]collections 真酷!!!(个从翻译) 原创空间, 软件技术
Green1 发表于 2005/3/27 8:47:26 VFP QQ群:4001858 VFP UC团体:4363524 欢迎您的加入 |
collections 真酷!!!
翻译:吕国瑞
QQ:61951565
VFP群:4001858
文章来源:http://www.code-magazine.com/Article.aspx?quickid=0301042
500)this.width=500'>欢迎共同探讨
做为一个程序员,你肯定使用过treeview控件,那么你一定对nodes对象不陌生。nodes对象其实是一个collection。本文将向你介绍VFP8中的collection类。你可以将collection理解为“集合”,“收集器”。
Collections是一种存储多个实例的通用方式。例如,TreeView控件有一个Nodes collection,Microsoft word有一个Documents collection。直到前不久,想使用Collection的Visual FoxPro开发者常常是通过创建自己的类实现的,这个类只不过是数组的封装。但是,这样做除了要写很多的代码外,自制的collections也不支持FOR EACH语法,这样的collections在COM服务中会很难使用的。VFP8通过提供一个真正的Collection基类解决了这一问题。
Collection基类只有很少的几个属性,事件和方法。ADD方法添加一个项目(item)到collecion中,Remove方法移去一个项目,Item方法返回一个项目。Count属性指明在collection中有多少个项目。一个项目(item)可能是一个数值也可能是文本,但更多的时候是一个对象(object)。collection除了可以保存项目(item)之外,还可以为每个项目(item)赋一个关键字值,如同给项目起了一个名子。可以通过下面所讲的方式定位一个项目(item):
位置:collection.item(2)返回collection中的第二个项目
关键字值:collection.item('doug')返回关键字值为"doug"的项目
由于 Item是默认方法,你可以忽略它,如果你愿意。Collection.item(2) 和 Collection(2)效果相同。
Collections可以是数组的简单代替。Collection中的每个项目类似于数组中的一行。但是由于collections是对象,因此它有更大的容量。这篇文章将探究colections的三个典型应用。
使用collections代替数组
将collections作为参数传递
在collections中使用collections
总结
清单1
使用collections代替数组
一些对象需要存储一些东西。比如,一个表单管理器需要得到在一个应用程序中所有打开的表单的信息。除了要得到指向表单对象的引用,它可能还需要知道在表单中使用了哪个工具条(这样你就没有同一个工具条的多个实例),表单是否被添加到窗口菜单,表单实例的数目(以防同一个表单被重复打开),等等。在VFP8以前,这些信息被保存在一个数组中,一行一个表单,一列一种信息类型。
但是,随着列数的增加,要想知道数组中是什么,在什么地方,变地越来越困难。是第四列存储实例数还是第七列存储实例数?同时,由于VFP中的数组没有0行,当一个表单关闭后你不得不谨慎地从数组中移去相应项目:
lnForms = alen(This.aForms, 1) ? 1lnCols = alen(This.aForms, 2)if lnForms = 0 This.aForms = .NULL.else* lnForm is the row number of the closed form adel(This.aForms, lnForm) dimension This.aForms[lnForms, lnCols]endif
使用collection将使这些复杂的事情简化。在collection中一个表单将以一个对象的形式存在,还不是数组中的一行。对象包含了对表单的引用以及其它需要的信息。你愿意写哪种代码去查找一个表单的实例数目?
* 基于数组的代码lnPos = ascan(This.aForms, 'CustomerForm')lnRow = asubscript(This.aForms, lnPos, 1)lnInstance = This.aForms[lnRow, 4]* 基于collection的代码lnInstance = ; This.oForms('CustomerForm').nInstance
从一个collection中移去一个项目也是很容易的,因为你不用担心数组的定义。只需要简单的调用collection的Remove方法。(返回目录)
将collections作为参数传递
设想你想要调用一个函数,这个函数填充一个数组并且这个数组是一个对象的成员。由于数组必须使用@操作符以引用的方式传递,但@操作符不能与成员数组一起使用,因此你不得不传递一个本地数组并使用ACOPY()函数将本地数组拷贝到成员数组中。为了避免错误,你必须首先定义成员数组。我在很多应用中有很多类似于这种情况的代码:
dimension laItems[1]SomeFunction(@laItems)lnRows = alen(laItems, 1)lnCols = alen(laItems, 2)dimension This.aItems(lnRows, lnCols)acopy(laItems, This.aItems)
使用成员collection而不是成员数组,一切将变得如此简单:
This.oItems = createobject('Collection')SomeFunction(This.oItems)
(返回目录)
在collections中使用collections一个collection中的的项目可以是任何东西,包括其它collections。除了表现地像多维数组,collections中的collections允许你使用简单的语法定位任何层次的对象。
假设你想使用“元数据”。使用下面的代码得到字段的数据类型不是很好的方法吗?
Tables('Products').Fields('ProductID').DataType
假设Tables是一个Table对象的collection,并且每个Table对象有一个Field对象的collection,并且一个Object对象有一个DataType属性,这是很容易做到的。
清单1是演示这种应用的示例。Table类的Init方法通过从CoreMeta.dbf表中读取元数据来组装表(tables)和字段(fields)的collections。CoreMeta.dbf表有关于表(tables)和字段(fields)的信息的列,包括cRecType("T"表示表,"F"表示字段),cObjectNam(表或字段名),cType(字段数据类型)。
为了得到Customer表的字段数,使用下列的语句:
Tables('customer').Fields.Count
你可以通过下面的语句得到order.order_date字段的描述:
Tables('orders').Fields('order_date').Caption
(返回目录)
总结
新的VFP8 collection基类使创建和使用项目的collections变得容易。虽然数组仍然有它的地位,我相信当VFP开发人员熟悉collection后,collection将在大部分应用中取代数组。
清单1
define class Tables as Collection procedure Init local lcTable, loTable, lcField, loField use CoreMeta scan do case* If this is a table, add it to the collection. case CoreMeta.cRecType = 'T' lcTable = trim(CoreMeta.cObjectNam) loTable = createobject('Table') This.Add(loTable, lcTable)* If this is a field, add it to the appropriate table. case CoreMeta.cRecType = 'F' lcTable = juststem(CoreMeta.cObjectNam) lcField = trim(justext(CoreMeta.cObjectNam)) loField = createobject('Field') with loField .DataType = CoreMeta.cType .Length = CoreMeta.nSize .Decimals = CoreMeta.nDecimals .Binary = CoreMeta.lBinary .AllowNulls = CoreMeta.lNull .Caption = trim(CoreMeta.cCaption) endwith This.Item(lcTable).Fields.Add(loField, lcField) endcase endscan use in CoreMeta endprocenddefinedefine class Table as Custom add object Fields as Collectionenddefinedefine class Field as Custom DataType = '' Length = 0 Decimals = 0 Binary = .F. AllowNulls = .F. Caption = ''enddefine |
|
回复:collections 真酷!!!(个从翻译) 原创空间, 软件技术
野骆驼(游客)发表评论于2006/4/3 21:13:15 VFP QQ群:4001858 VFP UC团体:4363524 欢迎您的加入 |
|
» 1 »
|