How to create VB.NET classes that enable For Each loops?

With code like the below...

    
Public Class clsFolder
    Public Name As String
    Public Size as Integer
End Class
Public Class clsFolders
    Dim oFolders As New List(Of clsFolder)
End Class

Open in new window

... how can I enable "For Each" enumeration over a variable declared as clsFolders with code like below? I've read about IEnumerable, which I assume is needed here, but I'm not tracking and any syntax I've attempted is incorrect.

Dim fols As New clsFolders
For Each fol As clsFolder In fols
    ' Gives compile error on "fols" above
Next

Open in new window

jjsatherAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

käµfm³d 👽Commented:
You can only For Each over something that implements IEnumerable. Within your clsFolders class you have something that implements IEnumerable:  oFolders. Loop over that:

Dim fols As New clsFolders
For Each fol As clsFolder In fols.oFolders
    ' do something
Next

Open in new window


Off-topic:

[1] Hungarian notation (e.g. clsXXXX) is not a recommended practice in .NET code. Just name your class "Folders" and be done with it.

[2] VB.NET is a case-insensitive language, but the commonly-accepted standard is to capitalize type names (i.e. class names). The same goes for property names in your classes.
2
it_saigeDeveloperCommented:
If you want clsFolders (or Folders; following Kaufmed's advice) to be an Enumerable type, then you must implement an Enumerable type; e.g. -
Module Module1
	Sub Main()
		Dim [folders] As Folders = New Folders(From i In Enumerable.Range(1, 10) Select New Folder With {.Name = $"Folder{i}", .Size = 10000 * i})
		For Each folder In folders
			Console.WriteLine(folder)
		Next
		Console.ReadLine()
	End Sub
End Module

Class Folder
	Public Property Name() As String
	Public Property Size() As Integer

	Public Overrides Function ToString() As String
		Return $"{{ Name: {Name}, Size: {Size} }}"
	End Function
End Class

Class Folders
	Implements ICollection(Of Folder)

	Private _items As ICollection(Of Folder)
	Public ReadOnly Property Count As Integer Implements ICollection(Of Folder).Count
		Get
			Return _items.Count()
		End Get
	End Property

	Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of Folder).IsReadOnly
		Get
			Return _items.IsReadOnly
		End Get
	End Property

	Public Sub New()
		_items = New List(Of Folder)
	End Sub

	Public Sub New(ByVal capacity As Integer)
		_items = New List(Of Folder)(capacity)
	End Sub

	Public Sub New(ByVal collection As IEnumerable(Of Folder))
		_items = New List(Of Folder)(collection)
	End Sub

	Public Sub Add(item As Folder) Implements ICollection(Of Folder).Add
		_items.Add(item)
	End Sub

	Public Sub Clear() Implements ICollection(Of Folder).Clear
		_items.Clear()
	End Sub

	Public Sub CopyTo(array() As Folder, arrayIndex As Integer) Implements ICollection(Of Folder).CopyTo
		_items.CopyTo(array, arrayIndex)
	End Sub

	Public Function Contains(item As Folder) As Boolean Implements ICollection(Of Folder).Contains
		Return _items.Contains(item)
	End Function

	Public Function Remove(item As Folder) As Boolean Implements ICollection(Of Folder).Remove
		Return _items.Remove(item)
	End Function

	Public Function GetEnumerator() As IEnumerator(Of Folder) Implements IEnumerable(Of Folder).GetEnumerator
		Return _items.GetEnumerator()
	End Function

	Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
		Return _items.GetEnumerator()
	End Function
End Class

Open in new window

Or inherit from a type that implements an Enumerable type -
Module Module1
	Sub Main()
		Dim [folders] As Folders = New Folders(From i In Enumerable.Range(1, 10) Select New Folder With {.Name = $"Folder{i}", .Size = 10000 * i})
		For Each folder In folders
			Console.WriteLine(folder)
		Next
		Console.ReadLine()
	End Sub
End Module

Class Folder
	Public Property Name() As String
	Public Property Size() As Integer

	Public Overrides Function ToString() As String
		Return $"{{ Name: {Name}, Size: {Size} }}"
	End Function
End Class

Class Folders
	Inherits List(Of Folder)

	Public Sub New()
		MyBase.New()
	End Sub

	Public Sub New(ByVal capacity As Integer)
		MyBase.New(capacity)
	End Sub

	Public Sub New(ByVal collection As IEnumerable(Of Folder))
		MyBase.New(collection)
	End Sub
End Class

Open in new window

Each of which produce the same output -Capture.PNG-saige-
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Kelvin McDanielSr. Developer/ConsultantCommented:
I think you might be over-thinking this one. You simply need to make the property you want to iterate over be a collection type OR a generic collection of said type. In today's world the latter is the preferred, best practice way because it simplifies things immensely while providing all the functionality you're looking for.

So, the property you want to iterate over needs to be:
Dim fols as New List (of clsFolders)

Open in new window

I assume you have a class grouping folders together because you want to add other properties/functions/whatever to that class in addition to the collection of folders that is already there. If that was not your intent, then you only need to do the following (as @käµfm³d has already implied):
Dim fols as New List(of clsFolder)

For Each folder as clsFolder in fols
    ' Actionable code
Next  

Open in new window

0
jjsatherAuthor Commented:
Just doing Inherits is all I ultimately needed. Thanks...

Public Class clsFolder
    Public Name As String
    Public Size as Integer
End Class
Public Class clsFolders
    Inherits List(Of clsFolder)
    Public Sub New()
        MyBase.New()
    End Sub
End Class

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.