为什么自己做的集合类不能使用for each 循环列举成员

ndsc213456789 2014-08-10 12:15:06
我模拟做了一个Collection集合类,可以实现Collection的基本功能。类模块如下(类名为Coll):
Dim Count_ As Long
Dim M_()

Public Sub Add(Item)
On Error Resume Next
Count_ = Count_ + 1
ReDim Preserve M_(Count_)
Err.Clear
Set M_(Count_) = Item '可以添加对象
If Len(Err.Description) <> 0 Then M_(Count_) = Item
End Sub

Public Function Count() As Long
Count = Count_
End Function

Public Function Item(index) ‘此处已经通过菜单中’过程属性‘把item函数设为缺省成员
On Error Resume Next
Err.Clear
Set Item = M_(index)
If Len(Err.Description) <> 0 Then Item = M_(index)
End Function



在使用类模块时其他的功能都正常,但不能用for eah 列举类成员。
Private Sub Form_Load()
Dim c1 As New Collection
Dim c2 As New Coll '自己定义的集体类
c1.Add "abcd"
c1.Add "abcd"
c1.Add "abcd"
c1.Add "abcd"
For Each j In c1
Debug.Print j 'collection集合可以正常列出集合成员
Next
c2.Add "1234"
c2.Add "1234"
c2.Add "1234"
c2.Add "1234"

For i = 1 To c2.Count
Debug.Print c2(i) '可以正常运行
Next

For Each j In c2 '运行此处显示对象不支持该方法
Debug.Print j
Next


End Sub



...全文
320 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ndsc213456789 2014-08-12
  • 打赏
  • 举报
回复
编这个东西是想了解类的一些特性,收获很多,感谢大家的回答,尤其感谢Tiger_Zhao,结贴!
threenewbee 2014-08-11
  • 打赏
  • 举报
回复
最简单的是用VB6附带的集合向导来产生集合类。 在工具-外接程序中可以找到这个向导。
ndsc213456789 2014-08-11
  • 打赏
  • 举报
回复
引用 3 楼 Tiger_Zhao 的回复:
[quote=MSDN帮助]创建自己的集合类:砖块盖的房子 要使 Item 成为缺省的属性,请按照以下步骤执行: 1.在“工具”菜单上,单击“过程属性”,打开“过程属性”对话框。在“名称”框中,选择 Item 方法。 2.单击“高级”,显示高级功能。在“过程标识符”框中,选择“(缺省)”,使 Item 方法成为缺省的。单击“确定”。 注意 一个类只能有一个缺省成员(属性或者方法)。 使 For Each ... Next 有效 伴随着强健性而来的,是重新获得了 For Each ... Next。通过添加下面的方法,可以再一次将所有工作委派给 Collection 对象:
'NewEnum 必须返回一个集合的枚举算子的 IUnknown 接口。
Public Function NewEnum() As IUnknown
   Set NewEnum = mcolEmployees.[_NewEnum]
End Function
要隐藏 NewEnum 方法,并将所需的过程 ID 赋给它,请按照以下步骤执行: 1.在“工具”菜单上,单击“过程属性”,打开“过程属性”对话框,在“名称”框中,选择 NewEnum 方法。 2.单击“高级”,显示一些高级功能。选中“隐藏该成员”,使 NewEnum 隐藏在类型库中。 3.在“过程标识符”框中,键入 -4,将 For Each ... Next 所需要的过程标识符赋给 NewEnum。单击“确定”。 重点 为了使自己的集合类使用 For Each ... Next 来工作,必须提供有正确过程标识符的隐藏 NewEnum 方法。
[/quote]这样做的话,所谓自己的集合类其实还包含着另一个标准集合类(mcolEmployees as collection )啊,但我写的集合类是用数组来存储对象成成员的,又应当怎么做呢?
Tiger_Zhao 2014-08-11
  • 打赏
  • 举报
回复
MSDN帮助
创建自己的集合类:砖块盖的房子

要使 Item 成为缺省的属性,请按照以下步骤执行:
1.在“工具”菜单上,单击“过程属性”,打开“过程属性”对话框。在“名称”框中,选择 Item 方法。
2.单击“高级”,显示高级功能。在“过程标识符”框中,选择“(缺省)”,使 Item 方法成为缺省的。单击“确定”。
注意 一个类只能有一个缺省成员(属性或者方法)。

使 For Each ... Next 有效
伴随着强健性而来的,是重新获得了 For Each ... Next。通过添加下面的方法,可以再一次将所有工作委派给 Collection 对象:
'NewEnum 必须返回一个集合的枚举算子的 IUnknown 接口。
Public Function NewEnum() As IUnknown
Set NewEnum = mcolEmployees.[_NewEnum]
End Function


要隐藏 NewEnum 方法,并将所需的过程 ID 赋给它,请按照以下步骤执行:
1.在“工具”菜单上,单击“过程属性”,打开“过程属性”对话框,在“名称”框中,选择 NewEnum 方法。
2.单击“高级”,显示一些高级功能。选中“隐藏该成员”,使 NewEnum 隐藏在类型库中。
3.在“过程标识符”框中,键入 -4,将 For Each ... Next 所需要的过程标识符赋给 NewEnum。单击“确定”。
重点 为了使自己的集合类使用 For Each ... Next 来工作,必须提供有正确过程标识符的隐藏 NewEnum 方法。
Tiger_Zhao 2014-08-11
  • 打赏
  • 举报
回复
用我5楼链接中给出的方法是可行的。
只不过他的 ICollection.Item 只支持 Object 类型,还不能直接用在非对象成员上。
'Calss: ValueObject'
'先得将值封装在对象中'

Option Explicit

Private m_Value As Variant

'属性要设为 (Default)'
Public Property Get Value() As Variant
Value = m_Value
End Property

Public Property Let Value(ByVal RHS As Variant)
m_Value = RHS
End Property

'为方便使用,在任意模块中加个封装的函数'

Public Function ValueObject(ByVal v As Variant) As ValueObject
Dim obj As New ValueObject
obj.Value = v

Set ValueObject = obj
End Function

'调用'
c2.Add ValueObject("1234")
c2.Add ValueObject("1234")
c2.Add ValueObject("1234")
c2.Add ValueObject("1234")

For Each j In c2 '成功使用 For Each
Debug.Print j '由于 ValueObject 的默认属性 Value,所以该语句依旧可以输出字符串'
Next

这样一改使用更麻烦。
ndsc213456789 2014-08-11
  • 打赏
  • 举报
回复
http://bbs.csdn.net/topics/70021145 这里面有讲,看来是实现一个小小的for each ...next 是不可能的了。
Tiger_Zhao 2014-08-11
  • 打赏
  • 举报
回复
需要实现 EnumVARIANT,参考
平头哥哥 2014-08-10
  • 打赏
  • 举报
回复

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧