Home All Groups Group Topic Archive Search About
Author
11 Sep 2006 10:05 PM
Buc
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

Author
11 Sep 2006 9:16 PM
GhostInAK
Hello Buc,

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

-Boo

Show quoteHide quote
> 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
Author
11 Sep 2006 10:39 PM
Tom Shelton
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.

Buc wrote:
Show quoteHide quote
> 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

--
Tom Shelton
Author
11 Sep 2006 10:51 PM
Dennis
How about a shorter version:

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

--
Dennis in Houston


Show quoteHide quote
"Tom Shelton" wrote:

>
> 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.
>
> Buc wrote:
> > 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
>
> --
> Tom Shelton
>
>
Author
11 Sep 2006 11:03 PM
Tom Shelton
Dennis wrote:
> 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 Shelton
Author
11 Sep 2006 11:09 PM
Tom Shelton
Tom Shelton wrote:
> Dennis wrote:
> > 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.

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.

--
Tom Shelton
Author
12 Sep 2006 11:26 PM
Dennis
You are correct in that it doesn't work for structures but works well for
classes and that's what I mostly use.
--
Dennis in Houston


Show quoteHide quote
"Tom Shelton" wrote:

>
> Dennis wrote:
> > 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 Shelton
>
>
Author
13 Sep 2006 1:19 AM
Tom Shelton
Dennis wrote:
> 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) :)

--
Tom Shelton
Author
12 Sep 2006 2:28 PM
Buc
I made it a class and the problem cleared up.
Thanks..

Show quoteHide quote
<Buc> wrote in message news:u$Q07Xe1GHA.328@TK2MSFTNGP06.phx.gbl...
>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
>
>