Results 1 to 5 of 5
  1. #1

    Thread Starter
    New Member
    Join Date
    Oct 2017

    Having Issues using Array Of Records

    My project is to have an array of records predefined and then have them output into a list box at high school using the following syntax https://i.stack.imgur.com/GfD8M.png however it outputs the error "System.Exception: 'Late-bound assignment to a field of value type 'Contact' is not valid when 'Contact' is the result of a late-bound expression.'"

    I've tried lots of troubleshooting and can't find the issue - it's probably something really simple. I'd appreciate any help you guys can offer.

    Public Class Form1
        'Dim addressbook(8, 2) As String
        'Dim number As i
        Structure Contact
            Dim Forename As String
            Dim Surname As String
            Dim address As String
        End Structure
        Dim addressbook(8) As Contact
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        End Sub
        Sub setuprecords(ByRef addressbook)
            'For row = 0 To 8
            ' For column = 0 To 2
            ' If column = 0 Then
            ' addressbook(row, column) = InputBox("What is your name ")
            ' ElseIf column = 1 Then
            ' addressbook(row, column) = InputBox("What is your 2nd name")
            ' ElseIf column = 2 Then
            ' addressbook(row, column) = InputBox("What is your address")
            ' End If
            ' Next
            addressbook(0).Forename = "Bart"
            addressbook(0).Surname = "Simpson"
            addressbook(0).address = "Springfeild"
            addressbook(1).Forename = "Lisa"
            addressbook(1).Surname = "Simpson"
            addressbook(1).address = "Springfeild"
            addressbook(2).Forename = "Homer"
            addressbook(2).Surname = "Simpson"
            addressbook(2).address = "Springfeild"
            addressbook(3).Forename = "Marge"
            addressbook(3).Surname = "Simpson"
            addressbook(3).address = "Springfeild"
            addressbook(4).Forename = "Santa's Little Helper"
            addressbook(4).Surname = "Simpson"
            addressbook(4).address = "Springfeild"
            addressbook(5).Forename = "Magie"
            addressbook(5).Surname = "Simpson"
            addressbook(5).address = "Springfeild"
            addressbook(6).Forename = "Milhouse"
            addressbook(6).Surname = "Something"
            addressbook(6).address = "Springfeild"
            addressbook(7).Forename = "Ned"
            addressbook(7).Surname = "Flanders"
            addressbook(7).address = "Springfeild"
            addressbook(8).Forename = "Willie"
            addressbook(8).Surname = "Something"
            addressbook(8).address = "Springfeild"
        End Sub
        Sub displayoutput(ByVal addressbook)
            'If number = 0 Then
            ' For row = 0 To 8
            ' ListBox1.Items.Add(addressbook(row, 0) & vbTab & (addressbook(row, 1) & vbTab & (addressbook(row, 2))))
            ' Next
            ' ' ListBox1.Items.Add(addressbook(number - 1 & vbTab & column))
            ' ListBox1.Items.Add(addressbook(number - 1, 0) & vbTab & (addressbook(number - 1, 1) & vbTab & (addressbook(number - 1, 2))))
            'End If
            For row = 0 To 8
        End Sub
    End Class

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002

    Re: Having Issues using Array Of Records

    There's something here that I always forget, so I may be totally offbase on this, but try changing Contact from a structure to a class. Structures are value types, classes are reference types.

    Another thing to do is to go into Project | Properties, go to the Compile tab, and set Option Strict ON for the project. This will likely point out at least a part of the problem. Late binding is only possible with Option Strict OFF (when you need to use late binding, which is occasionally essential, you have to set Option Strict OFF for the page), and the exception talks about late binding. Normally, you want to work with Option Strict ON because it will force you to write safer (and slightly faster) code, since it disallows implicit conversions.
    My usual boring signature: Nothing

  3. #3
    New Member
    Join Date
    Oct 2017

    Re: Having Issues using Array Of Records

    How do you make a post in this forum?

  4. #4
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Bristol, UK

    Re: Having Issues using Array Of Records

    Welcome to VBForums
    Quote Originally Posted by Justin Jake Ashton View Post
    How do you make a post in this forum?
    You just did, but as a reply to an existing topic... if that is what you want (because you want to help answer the question), then clicking on "Reply to Thread" (or typing in the Quick Reply box below) is the way to do it.

    If you want to create a new thread (because you have a question to ask) then go here: http://www.vbforums.com/index.php (or just http://www.vbforums.com ) and pick the forum that seems appropriate for your question. Click on it, then in the page that loads click on "Post New Thread".

  5. #5
    You don't want to know.
    Join Date
    Aug 2010

    Re: Having Issues using Array Of Records

    Definitely turn Option Strict On. But you also have to provide types for your variables. When VB talks about "late binding" it means you're using a variable of type Object, which means it has to hope you know what you're doing when you access properties.

    With Option Strict On, this will be invalid:
    Sub setuprecords(ByRef addressbook)
    When VB complains about this, the error message means, "I need you to tell me what type 'addressbook' will be so I can stop you from making mistakes." 'addressbook' will be an "array of Contact", so the code should change to:
    Sub setuprecords(ByRef addressbook() As Contact)
    The specific reason this broke in your program is highly technical, but a good takeaway is "forget Structures exist until you've been writing code a lot longer". In VB .NET we use Classes for just about everything, and only use Structures in very rare circumstances.

    Don't read any further if you don't want to see nerd stuff, but do remember "never use a Structure again". By the time you need a Structure you'll have learned enough to understand WHY you need one.

    The reason is Structures are "value types". Put simply that means they go in a different part of memory than Classes and they also behave differently when you assign them to each other.

    String is a class. If I write this code, I end up with two variables that both mean the same String:
    Dim version1 As String = "Hello"
    Dim version2 As String = version1
    If we could change Strings, changing version2 would also appear to change version1, but what's really happening is there is only one String and both variables point at it. This is like how on the forums you call me "Sitten Spynne", but in real life people call me a different name. There's only one me, but lots of different names I'll respond to.

    Structures work differently. They are copied every time you assign them.
    Dim version1 As Integer = 3
    Dim version2 As Integer = version1
    This creates TWO different Integers that hold the value 3, and each variable has its own copy. This is like if we're watching a baseball game and I've got a hot dog, and you decide you want a hot dog too. So you ask me where I got it, I point at a hot dog stand, and you go buy one. We have two hot dogs.

    So variables care about if they are "a class" or "a structure", and you can't really mix the two easily. There is no way to store "a class" in a variable that is "a structure". But thanks to complexity, the Object variable type has to be able to store everything so this works:
    Dim version1 As Integer = 3
    Dim version2 As Object = version1
    Now here's where things get super weird. How did the structure go inside a class variable? What VB does is construct a very special object called a "box". No, I'm not making that up. The box is a class. VB makes a copy of version1 and puts it in the box. Then it assigns the box to the variable 'version2'. When you try to do something with that variable, VB opens the box, makes a copy of the Integer inside, then gives that Integer to you.

    I don't have a real-world analogy for this because I'd need to use magic and I don't want to have to explain VB and magic in the same post.

    SO. Your code failed because this line has absolutely no chance of doing what you want due to the special behavior of Structures:
    addressbook(3).Forename = "Marge"
    Here's why.

    'addressbook' is an Object variable because you declared no type in the parameter list. Arrays are always treated as class types. The (3) part is actually translated, by the compiler, to .Item(3). Since the compiler doesn't know the type of the array, it assumes Object. So 'addressbook(3)' is a boxed Contact. VB unboxes Contact and gives you a copy. Then you set the 'Forename' property on that copy. Since it's not the same Contact as the one inside the box, that means you won't see the change.
    Because of how confusing that might be, the compiler developers decided to look for this scenario and treat it as an error.

    The only possible way you could make this work would be:
    Dim fourthContact As Contact = addressbook(3) ' Makes a copy
    fourthContact.Forename = "Marge"              ' Changes the copy
    addressbook(3) = fourthContact                ' Replace the old value with the new value
    Because of how difficult and tedious that is, you rarely want to use Structures instead of Classes.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts


Click Here to Expand Forum to Full Width