1

I have defined a structure in my code and have a list of this structures"

Structure Parcel
        Public name As String
        Public type As String                 
    End Structure

  Dim ParcelList As New List(Of Parcel)

Then I'm trying to set some values to an element of the list which name is known to me

For Each myParcel As Parcel In ParcelList
                If (myParcel.name = "Parcel1") Then
                    myParcel.type="Type1"
                End If
            Next

Unfortunately values in my list don't change at all. what am I doing wrong?

RRM
  • 3,371
  • 7
  • 25
  • 40

3 Answers3

4

As Parcel is a Structure, it is passed by value so when iterating through collection, you are modifying a copy of your structure.

To better understand this case, you should understand what For Each really is. Your code can be translated into:

Dim enumerator As List(Of Parcel).Enumerator = ParcelList.GetEnumerator()
While enumerator.MoveNext()
    ' Here you have a local copy of your Structure
    Dim myParcel As Parcel = enumerator.Current
    Dim flag As Boolean = Operators.CompareString(myParcel.name, "Parcel1", False) = 0
    If flag Then
       ' Here you modify your local copy
       myParcel.type = "Type1"
    End If
End While

If Parcel was a Class, it would be passed by reference so no local copy would be created and line myParcel.type = "Type1" would change proper object existing in your collection.

Konrad Kokosa
  • 16,563
  • 2
  • 36
  • 58
1

As already Stated this is because you are modifying a local copy of a value type. One way round this is to access the items in the list by ordinal and replace the ordinal value type with a new type:

    For i As Integer = 0 To ParcelList.Count - 1
        If ParcelList(i).name = "Parcel1" Then
            ParcelList(i) = New Parcel With {.name = ParcelList(i).name, .type = "Type1"}
        End If
    Next

But really you should change the Sturcture to a Class

Matt Wilko
  • 26,994
  • 10
  • 93
  • 143
-3

When checking for strings use Equals instead of '='.

            If (myParcel.name.equals("Parcel1")) Then
                myParcel.type="Type1"
            End If

Strings are in fact 'Objects'. When you compare Strings (example StringA = StringB), you check the allocation of the String in Memory instead of the contents of the string.

Even better would be:

            If (myParcel.name.ToUpper().equals(Cstr("Parcel1").toUpper())) Then
                myParcel.type="Type1"
            End If

That way you ignore any difference case-wise. example: myParcel.name = "teST"

             myParcel.name.equals("test") 
                  is False
             myParcel.name.ToUpper().equals(Cstr("test").toUpper())
                  is true
User999999
  • 2,500
  • 7
  • 37
  • 63