Hi,
There is a sample in the help for VS called "HOW TO: Make a Visual Basic .NET Class Usable in
a For Each
Statement".
For Each c In carz
Console.WriteLine(c.Make & t & c.Year)
Next
The second iteration never happens. Any help appreciated.

Implementing For Each. I'm guessing this is to do with internal pointers.
MSDevUser
Hi,
Why not use Ubound instead of FOR EACH to get the upperBound limit of your array >>
Dim index , loopIndexas integer
index=Ubound(carz)
For loopIndex=0 to index
Console.WriteLine(carz(loopIndex).c.Make & _
t & (carloopIndex).c.Year) ' or similiar as you can have an array
'of any kind of object or CLASS
Next
Regards,
S_DS
mm_ezzo
No internal pointer the class implements enumeration and there is a reset function that I assume should be called as part of the FOR initialisation, that routine sets the position variable to -1 which is just before the beginning of the set as the first iteration adds one to it. That I do not have a problem with, just wondering why if a reset function is required it is never called or why the FOR EACH is not calling it as part of its initialise. See the example code in Help.
Michael.
motorola
Can you show the code for "cars"
In order to participate in for each, you must implement the enumerator pattern correctly. See this article for more details. In particular make sure that you have implemented Reset() correctly. You can set a breakpoint in your implementation of Reset() and MoveNext() to be sure that everything works as expected.
sudheer_316
Here is the complete modified code with my own implementation (Using Tax not Cars) of dynamically adding TaxEntry at runtime and solution to make the position initialise to -1 on the first run through after it has run through... THis is just the test routine I used to try to understand it, much more functionality and behaviour has been added to the final working solution, I would encourage anyone to use FOR EACH as it simplifies code once you get your head round it, doing a walkthrough helps.
Option Explicit On
Option Strict On
Imports System.Collections
Public Class Taxes : Implements IEnumerator, IEnumerable
Private position As Integer = -1
Private TaxTables(0) As TaxEntry
Public Sub Add(ByVal Code As Integer, ByVal Percent As Decimal)
If Not TaxTables(TaxTables.GetUpperBound(0)) Is Nothing Then
ReDim Preserve TaxTables(TaxTables.GetUpperBound(0) + 1)
End If
TaxTables(TaxTables.GetUpperBound(0)) = New TaxEntry(Code, Percent)
End Sub
Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return CType(Me, IEnumerator)
End Function
Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext
'
' If we have walked through once then position will not be < length so this must be a new
' run through so set position to 0.
'
If (position < TaxTables.Length) = False Then
position = 0
else
position += 1
End If
Return (position < TaxTables.Length)
End Function
Public Sub Reset() Implements IEnumerator.Reset
position = -1
End Sub
Public ReadOnly Property Current() As Object Implements IEnumerator.Current
Get
Return CType(TaxTables(position), TaxEntry)
End Get
End Property
End Class
Imports System.Collections
Public Class TaxEntry
Private myTaxCode As Integer
Private myPercentage As Decimal
Private myTaxAmount As Decimal
Public Sub New(ByVal Code As Integer, ByVal Percent As Decimal)
myTaxCode = Code
myPercentage = Percent
myTaxAmount = 0.0
End Sub
Public Property TaxCode() As Integer
Get
Return myTaxCode
End Get
Set(ByVal value As Integer)
myTaxCode = value
End Set
End Property
Public Property TaxPercent() As Decimal
Get
Return myPercentage
End Get
Set(ByVal Value As Decimal)
myPercentage = Value
End Set
End Property
Public Property TaxAmount() As Decimal
Get
Return myTaxAmount
End Get
Set(ByVal Value As Decimal)
myTaxAmount = Value
End Set
End Property
End Class
Module Module1
Sub Main()
Dim TaxTest As New Taxes()
TaxTest.Add(1, 0.0)
TaxTest.Add(2, 17.5)
Dim v As TaxEntry
For Each v In TaxTest
Console.WriteLine(v.TaxCode & " " & v.TaxPercent)
Next
Console.ReadLine()
For Each v In TaxTest
Console.WriteLine(v.TaxCode & " " & v.TaxPercent)
Next
Console.ReadLine()
End Sub
End Module
GarethKeen
Hi,
Try the CODE IN THIS COLOUR FIRST.
Try doing the next run through within a new sub or set a GLOBAL variable for the number of times you want the ForEach loop executed.
i.e.>>
The 1st line here would be after the>>
WINDOWS FORM DESIGNER GENERATED CODE section.
Private iterationsCount As Integer=2
Sub Main()
Dim c As car
Dim t As String = vbTab & vbTab
Dim n As String = vbCrLf
Dim carz As cars = New cars()
Console.WriteLine(n & "Internal Collection" & n)
For Each c In carz
Console.WriteLine(c.Make & t & c.Year)
Next
Console.ReadLine()
If iterationsCount >0 Then
iterationsCount =iterationsCount -1
Main()
Else
Exit Sub
End If
End Sub
____________________________________________________
Alternatively try the code with the 1st readline taken out.
My guess it ReadLine is resetting the pointer in the collection of objects or moving the pointer past the collection end point.
Sub Main()
Dim c As car
Dim t As String = vbTab & vbTab
Dim n As String = vbCrLf
Dim carz As cars = New cars()
Console.WriteLine(n & "Internal Collection" & n)
For Each c In carz
Console.WriteLine(c.Make & t & c.Year)
Next
' Console.ReadLine() 'TRY TAKING THIS LINE OUT
Console.WriteLine(n & "Internal Collection" & n)
For Each c In carz
Console.WriteLine(c.Make & t & c.Year)
Next
Console.ReadLine()
End Sub
My final idea is to have the main Sub call the rest of the code
the number of times you want it to, within a FOR NEXT loop
as in>>
Sub Main ()
Dim index as Integer=0
For index=1 to 2
LoopCode()
Next
End Sub
Private Sub LoopCode()
Dim c As car
Dim t As String = vbTab & vbTab
Dim n As String = vbCrLf
Dim carz As cars = New cars()
Console.WriteLine(n & "Internal Collection" & n)
For Each c In carz
Console.WriteLine(c.Make & t & c.Year)
Next
Console.ReadLine()
End Sub
By the way i've not actally tried any of the above, they are just suggestions, i hope one works for you. :-)
Regards,
S_DS