How to enumerate enumerations in VB.Net Framework 2.0 - ΩJr. Software Articles and Products

This information lives on a web page hosted at the following web address: 'https://omegajunior.globat.com/code/'.

Nice, those enumerated lists. But what if you need all the names and integer values for all the items in the list?

A.E.Veltstra
Feb. 28, 2007

Clean working example


Private Sub Enumerate()
Dim sf As System.Environment.SpecialFolder
For Each sf In System.Enum.GetValues(sf.GetType())
Console.WriteLine("{0}: {1}", sf.ToString(), _
System.Environment.GetFolderPath(sf))
Next
End Sub



How did we get there?


Imagine you wish to build a hash of the names of the SpecialFolder enumeration, and their accompanying folder paths. Imagine you don't want to code all the names by hand, because a) you're a programmer and not a typist, and b) because the enumeration may change depending on the system and framework. Thus you set out to look for a way to enumerate enumerations.

So I looked around in System.Environment.SpecialFolder and found a method GetNames() and a method GetValues(). They return System.Arrays holding a enumerations. Since I don't only need the names but the integer values as well, I chose to query the GetValues(). Then I can instantiate a variable of type SpecialFolder to loop through all items in the array using For Each. Unfortunately, Visual Basic doesn't allow us to call the GetValues() method from the instantiated variable. Meaning this doesn't work:

Incorrect example
Private Sub Enumerate()
Dim sf As System.Environment.SpecialFolder
Dim arrValues as Array = sf.GetValues() 'this fails!
For Each sf In arrValues
Console.WriteLine(sf.ToString())
Next
End Sub

But it didn't work... GetValues() can't be called from an instance... it has to be called from the type directly. So I tried this:

Incorrect example 2
Private Sub Enumerate()
Dim arrValues as Array = _
System.Environment.SpecialFolder.GetValues() 'this fails too!
Dim sf As System.Environment.SpecialFolder
For Each sf In arrValues
Console.WriteLine(sf.ToString())
Next
End Sub

And that also failed! For some inane reason, GetValues() expects a type parameter... why doesn't it simply inherit the type from SpecialFolder? I guess the .Net Framework isn't as Object Oriented as it claims.

So how do you hand a method a type? Simply entering the type itself (System.Environment.SpecialFolder) doesn't work... not in VB2005. Doesn't work if I try passing it as a string, either. How do I turn this into a type the language accepts? I found I could use GetType(System.Environment.SpecialFolder):

Silly but working example
Private Sub Enumerate()
Dim arrValues As Array = _
System.Environment.SpecialFolder.GetValues( _
GetType(System.Environment.SpecialFolder)
)
Dim sf As System.Environment.SpecialFolder
For Each sf In arrValues
Console.WriteLine("{0}: {1}", sf.ToString(), _
System.Environment.GetFolderPath(sf))
Next
End Sub

But that's silly! That GetType() function is a language construct and SpecialFolder itself already has a GetType() method... can't I use that? Yes, I can. However, not directly from the type. That method requires an instance. Well I'll be damned: GetValues() refuses to work on an instance, while GetType() requires an instance... rather confusing, isn't it?

We solve this by not using SpecialFolder.GetValues(). Instead, we use that method from its structure, System.Enum. And we also don't use SpecialFolder.GetType() (because it doesn't work), and replace that by invoking from the instance. Which results in this:

Clean working example
Private Sub Enumerate()
Dim sf As System.Environment.SpecialFolder
For Each sf In System.Enum.GetValues(sf.GetType())
Console.WriteLine("{0}: {1}", sf.ToString(), _
System.Environment.GetFolderPath(sf))
Next
End Sub

There you have it: enumeration of an enumeration. Much cleaner than most examples I found! Stands to reason that we can use the same technique to enumerate our own enumerations.

Tags
.net, vb.net, visual basic, enumerate, enumeration, enum, specialfolder, getvalues, gettype, foreach, method, hierarchy, hierarchical, object orient

Need problem solving?

Talk to me. Let's meet for coffee or over lunch. Mail me at “omegajunior at protonmail dot com”.