Коллекции. For Each и интерфейс lEnumerable.
1 Public Class Employees 2 Implements IEnumerable.IEnumerator 3 Private m_Employees() As Employee 4 Private m_index As Integer = -1 5 Private m_Count As Integer = 0 6 Public Function GetEnumerator() As lEnumerator _ 7 Implements lEnumerable.GetEnumerator 8 Return Me 9 End Function 10 Public Readonly Property Current() As Object _ 11 Implements IEnumerator.Current 12 Get 13 Return m_Employees(m_Index) 14 End Get 15 End Property 16 Public Function MoveNext() As Boolean _ 17 Implements lEnumerator.MoveNext 18 If m_Index < m_Count Then 19 m_Index += 1 20 Return True 21 Else 22 Return False 23 End If 24 End Function 25 Public Sub Reset() Implements IEnumerator.Reset 26 m_Index = 0 27 End Sub 28 Public Sub New(ByVal theEmployees() As Employee) 29 If theEmployees Is Nothing Then 30 MsgBox("No items in the collection") 31 ' Инициировать исключение – см. главу 7 32 ' Throw New ApplicationException() 33 Else 34 m_Count = theEmployees.Length -1 35 m_Employees = theEmployees 36 End If 37 End Sub 38 End Class
Строка 2 сообщает о том, что класс реализует два основных интерфейса, используемых при работе с коллекциями. Для этого необходимо реализовать функцию, которая возвращает объект lEnumerator. Как видно из строк 6-9, мы просто возвращаем текущий объект Me. Впрочем, для этого класс должен содержать реализации членов IEnumerable; они определяются в строках 10-27.
Примечание
В приведенной выше программе имеется одна тонкость, которая не имеет никакого отношения к интерфейсам, а скорее связана со спецификой класса. В строке 4 переменная mjndex инициализируется значением -1, что дает нам доступ к 0 элементу массива, в результате чего первый вызов MoveNext предоставляет доступ к элементу массива с индексом 0 (попробуйте инициализировать mjndex значением 0, и вы убедитесь, что при этом теряется первый элемент массива).
Ниже приведена небольшая тестовая программа. Предполагается, что Publiс-класс Employee входит в решение:
Sub Main() Dim torn As New Emplpyee("Tom". 50000) Dim sally As New Employee("Sally". 60000) Dim joe As New Employee("Joe", 10000) Dim theEmployees(l) As Employee theEmployees(0) = torn theEmployees(1) = sally Dim myEmployees As New Employees(theEmployees) Dim aEmployee As Employee For Each aEmployee In myEmployees Console.WriteLine(aEmployee.TheName) Next Console.ReadLine() End Sub