Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to update elements within a List(Of Structure)?

Tags:

vb.net

If I am accumulating data with no advance information about the number of elements, I can use an array and enlarge it as necessary using Redim Preserve, but a List will usually be more efficient. For example:

Dim vehicle As New List(Of String)(4)

vehicle.Add("car")
vehicle.Add("bicycle")
vehicle.Add("truck")
vehicle.Add("taxi")
vehicle.Add("motorbike")
vehicle.Add("bus")

Even though my guess of 4 as the maximum number of elements was wrong, I can add new elements without problems.

I can display the elements so:

For inx = 0 To vehicle.Count - 1
    Debug.Print("    " & inx & " " & vehicle(inx))
Next

and get:

0 car
1 bicycle
2 truck
3 taxi
4 motorbike
5 bus

I can update elements as required and redisplay:

vehicle(2) = "coach"
vehicle(4) = "cart"

For inx = 0 To vehicle.Count - 1
    Debug.Print("    " & inx & " " & vehicle(inx))
Next

to get:

0 car
1 bicycle
2 coach
3 taxi
4 cart
5 bus

I can create a list of structures almost as easily:

Structure SpersonDtl
    Dim familyName As String
    Dim givenName As String
    Dim age As Integer
End Structure

Dim personDtl As New List(Of SpersonDtl)(4)
Dim personDtlCrnt As SpersonDtl

personDtlCrnt.familyName = "Smith"
personDtlCrnt.givenName = "John"
personDtlCrnt.age = 20
personDtl.Add(personDtlCrnt)

personDtlCrnt.familyName = "Brown"
personDtlCrnt.givenName = "Clare"
personDtlCrnt.age = 21
personDtl.Add(personDtlCrnt)

personDtlCrnt.familyName = "Wilson"
personDtlCrnt.givenName = "David"
personDtlCrnt.age = 22
personDtl.Add(personDtlCrnt)

personDtlCrnt.familyName = "Fox"
personDtlCrnt.givenName = "Wendy"
personDtlCrnt.age = 23
personDtl.Add(personDtlCrnt)

Displaying the list's contents with:

For inx = 0 To personDtl.Count - 1
    Debug.Print("    " & inx & " " & personDtl(inx).givenName & " " & _
                personDtl(inx).familyName & " " & personDtl(inx).age)
Next

gives:

0 John Smith 20
1 Clare Brown 21
2 David Wilson 22
3 Wendy Fox 23

If personDtl were an array, I could update an element easily. To correct Wendy's age, I would write:

personDtl(3).age = 24

However, the same statement with a list, results in a blue line under personDtl(3).age and the error message: "Expression is a value and therefore cannot be the target of an assignment."

The best solution I have found is:

Dim personDtlCrnt As SpersonDtl

personDtlCrnt = personDtl(3)
personDtlCrnt.age = 24
personDtl(3) = personDtlCrnt 'Write back.

In my application, I am accumulating information into large, complex structures. To copy an element out of the list, add one new item of information and then copy it back would not be an efficient process.

I would be grateful for any suggestions for an alternative approach.

like image 601
Tony Dallimore Avatar asked Jul 12 '12 22:07

Tony Dallimore


1 Answers

Try using a class instead of a structure.

From Choosing Between Classes and Structures

Consider defining a structure instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.

Do not define a structure unless the type has all of the following characteristics:

  • It logically represents a single value, similar to primitive types (integer, double, and so on).

  • It has an instance size smaller than 16 bytes.

  • It is immutable.

  • It will not have to be boxed frequently.

If one or more of these conditions are not met, create a reference type instead of a structure. Failure to adhere to this guideline can negatively impact performance.

You want your SpersonDtl "structure" to be mutable by changing one of the values, which is breaking one of those characteristics listed above.

like image 175
LarsTech Avatar answered Sep 30 '22 20:09

LarsTech