VB.NET Iterating through objects of a structure

10,531

Solution 1

If this is just a one time thing you're probably going to have an easier time using a Dictionary instead, but you could do this with Reflection if you prefer to keep the structure.

This little code snippet will list out each structure member for you in a StringBuilder.

Dim sbOutput As New System.Text.StringBuilder
Dim t As Type = GetType(xyz)
For Each p As System.Reflection.FieldInfo In t.GetFields()
  sbOutput.AppendLine(p.Name)
Next

Solution 2

An old question, but I actually found myself needing this, too, and this was one of the top results Google came up for me, so I figured I'd contribute for anyone who comes by this way in the future.

In my case, I'm basically using the structure as a collection of strings that I can easily reference via StrucName.Value1, etc (basically an Enum of strings, like asked about here), and not have to worry as much about spell checking (as you'd have to do with a dictionary, whether you were using the dict!foo method as commented on above or not). 90% of my usage I just need one or two of the values at a time, but I have found a spot or two in my code where it'd be nicer/easier to loop through all of the member values and perform (essentially) the same set of actions with each of them vs listing each one out on its own line.

I found a good answer to this that doesn't use reflection on another site, where one of the commenters suggested either overriding the ToString function, or using a function that returns an array of the values. Of course, technically, this still requires you writing out all the members of the structure again one more time, but if Reflection really is heavy on performance, then this may be better.

I ended up using the function to return an array method like below:

Public Structure StrucName
    Public Const Value1 As String = "Value1"
    Public Const Value2 As String = "Value2"
    Public Const Value3 As String = "Value3"
    'etc
    Public Shared Function GetMemberValues() As String()
        Return {Value1, Value2, Value3} 'etc
    End Function
End Structure

Then you can use it in code like this:

Dim values As String() = StrucName.GetMemberValues()
For Each value As String In values
    'do stuff
Next

If your structure is of multiple value types, then you can use an ArrayList, instead.

Public Structure StrucName
    Public Const Value1 As String = "Value1"
    Public Const Value2 As Integer = 2
    Public Const Value3 As Boolean = True
    'etc
    Public Shared Function GetMemberValues() As ArrayList
        Return New ArrayList From {Value1, Value2, Value3} 'etc
    End Function
End Structure
Dim values As ArrayList = StrucName.GetMemberValues()
For Each value As Object In values
    'do stuff
Next

And with the ArrayList method, if needed, you can get the type of the original value through value.GetType(), or any other similar operator or methods (so, with my example above, putting MsgBox(value.GetType().ToString()) in our "do stuff" area will pop message boxes with "System.String", "System.Int32", and "System.Boolean").

And I imagine this could be adapted to a number of situations. For example, if you needed both the member names and values, you could return a Dictionary:

Public Shared Function GetMemberValues() As Dictionary(Of String, Object)
    Return New Dictionary(Of String, Object) From {{"Value1", Value1}, {"Value2", Value2}, {"Value3", Value3}} 'etc
End Function

Or, if you're using a new enough version of VB (VB 14 or later), you can use the NameOf operator (MS Doc here):

Public Shared Function GetMemberValues() As Dictionary(Of String, Object)
    Return New Dictionary(Of String, Object) From {{NameOf(Value1), Value1}, {NameOf(Value2), Value2}, {NameOf(Value3), Value3}} 'etc
End Function
Dim values As Dictionary(Of String, Object) = StrucName.GetMemberValues()
For Each kvp As KeyValuePair(Of String, Object) In values
    'do stuff
Next

And kvp.value.GetType() still holds up.

Share:
10,531
Theveloper
Author by

Theveloper

"Make good bots and prosper. Long live RegEx."

Updated on June 09, 2022

Comments

  • Theveloper
    Theveloper almost 2 years

    I have a structure "xyz" with 3 string objects in it. "foo" "bar" and "abc" I want to iterate through the structure and compare the names of the objects.

    Structure xyz
        dim foo as string
        dim bar as string
        dim abc as string
    End Structure
    

    Pseudo:

    For each x as object in xyz 
        if x.Name = "foo" then
            'bang
        end if
    End each
    

    Is this possible?

  • schlebe
    schlebe over 2 years
    can you "improve" your answer in adding reflection code to add VALUE of p.Name variable ? Thanks