Arraylist Problem

  • Thread starter Thread starter GhostInAK
  • Start date Start date
G

GhostInAK

Hello Buc,

It means you cant change the struct element. You have to assign a new struct.

-Boo
 
I have a simple structure for example purposes I add to an array list

public structure MyStruct
dim counter as integer
end structure

dim mylist as ArrayList
dim x as New MyStruct

x.counter = 2
mylist.Add(x)
debug.writeline (mylist(0).counter) shows a value of 2

I try to change the value
mylist(0).counter = 3
and I get an error:

**Latebound assignment to a field of value type 'MyStruct'is not valid when
'MyStruct' is the result of a latebound expression.

What does this mean? How can I simply change the value of that element in
the arraylist?
Thanks
BUC
 
Before I attempt to answer this question, I would suggest that you
always specify what VB.NET version your using... Answers to questions
can vary based on that information. For example, in your case if your
using VB.NET 2005, then I would tell you not to use ArrayList at all -
but to use System.Collections.Generic.List.
I have a simple structure for example purposes I add to an array list

public structure MyStruct
dim counter as integer
end structure

dim mylist as ArrayList
dim x as New MyStruct

x.counter = 2
mylist.Add(x)
debug.writeline (mylist(0).counter) shows a value of 2

I try to change the value
mylist(0).counter = 3
and I get an error:

**Latebound assignment to a field of value type 'MyStruct'is not valid when
'MyStruct' is the result of a latebound expression.

That's because you don't have option strict on. You should pretty much
always have that on (there are interop situations where it is nice to
turn it off - but, for most code, you're asking for issues by not
turning it on).

VB.NET 1.1
Option Explicit On
Option Strict On

Imports System
Imports System.Collections

Module Module1

Structure MyStruct
Public counter As Integer

Public Sub New(ByVal initialValue As Integer)
counter = initialValue
End Sub
End Structure

Sub Main()
Dim myList As New ArrayList
Dim x As New MyStruct(2)

' set the initial value
myList.Add(x)

' change the element
Dim y As MyStruct = DirectCast(myList(0), MyStruct)
y.counter = 3
myList(0) = y

' get it back to show it was changed
Dim z As MyStruct = DirectCast(myList(0), MyStruct)
Console.WriteLine(z.counter)
End Sub

End Module


VB.NET 2005:

Option Explicit On
Option Strict On

Imports System
Imports System.Collections.Generic

Module Module1

Structure MyStruct
Public counter As Integer

Public Sub New(ByVal initialValue As Integer)
counter = initialValue
End Sub
End Structure

Sub Main()
Dim x As New MyStruct(2)
Dim myList As New List(Of MyStruct)
myList.Add(x)

Dim y As MyStruct = myList(0)
y.counter = 3
myList(0) = y

Dim z As MyStruct = myList(0)
Console.WriteLine(z.counter)
End Sub

End Module


All of this becomes a lot easier if you just make this a reference type
( a class rather then a value type)...

vb.net 1.1
Option Explicit On
Option Strict On

Imports System
Imports System.Collections

Module Module1

Class MyStruct
Public counter As Integer

Public Sub New(ByVal initialValue As Integer)
counter = initialValue
End Sub
End Class

Sub Main()
Dim myList As New ArrayList
Dim x As New MyStruct(2)

' set the initial value
myList.Add(x)

' change the element
DirectCast(myList(0), MyStruct).counter = 3

' get it back to show it was changed
Console.WriteLine(DirectCast(myList(0), MyStruct).counter)
End Sub

End Module

vb.net 2005:

Option Explicit On
Option Strict On

Imports System
Imports System.Collections.Generic

Module Module1

Class MyStruct
Public counter As Integer

Public Sub New(ByVal initialValue As Integer)
counter = initialValue
End Sub
End Class

Sub Main()
Dim x As New MyStruct(2)
Dim myList As New List(Of MyStruct)
myList.Add(x)

myList(0).counter = 3
Console.WriteLine(myList(0).counter)
End Sub

End Module

HTH
 
Dennis said:
How about a shorter version:

DirectCast(myList(0), MyStruct).counter = 3

Go ahead and try that when MyStruct is a value type and then report
back :)

Hint: Expression is a value and therefore cannot be the target of an
assignment.
 
Tom said:
Go ahead and try that when MyStruct is a value type and then report
back :)

Hint: Expression is a value and therefore cannot be the target of an
assignment.

I think for the OP, I will explain why, when using a value type
(structure) you have to assign it to a temp and then put it back in the
element....

The answer really comes down to the difference between value types and
reference types. A structure is a value type. When you retrieve the
value from the collection, what you really get is not the original
structure - but a copy of the structure. So, you have to capture that
value, modifiy the value, and then reassign it to the same element in
the collection.

When the value is a reference type (class), the value you get from the
collection is a reference to that object. What that means is that you
really getting returned the memory location of the real object. So,
when you operate on it, you are operating on the actual object, not a
copy as you are with a value type.
 
You are correct in that it doesn't work for structures but works well for
classes and that's what I mostly use.
 
Dennis said:
You are correct in that it doesn't work for structures but works well for
classes and that's what I mostly use.
--

Exactly... And if you go look at the several examples I posted, it's
exactly what I used when I showed that it was much easier when using a
reference type (class) :)
 
Back
Top