Search code examples
vb.netdictionaryinitialization

Member variable no initializing


I have started a new job and I need to write in vb.net

For the code I am writing, I need to map from an integer to a panel. I would like this mapping to have scope for the entire file, not just a single subroutine, so I have tried declaring it as such:

Private ReadOnly MAP = New Dictionary(Of Integer, Panel) From {
    {0, Nothing},
    {1, Foo},
    {2, Bar},
    ...
}

Then, I have a subroutine something like this (simplified)

Private Sub Thing(ID As Integer)
    If MAP.Item(ID) IsNot Nothing
        MAP.Item(ID).Visible = True
    End If
End Sub

and let say I call Thing(1), that should make Foo visible, but instead nothing happens. If I Dim MAP inside of Thing, it works as expected. I obviously don't want to be constructing my map everytime I call the sub though, as that kinda defeats the purpose of a map by adding the overhead of constructing it at every use (although it is more readable).

Basically what I'm wondering is why the construction of MAP doesn't remain when I use it? Shouldn't all member variables be constructed before we begin executing any of the methods of a class, if declared in this way?


Solution

  • The trick is here is Forms are classes, which have a defined initialization order where fields (like MAP) are initialized before the constructor runs. This makes sense. If you have a complex constructor, you would want and expect to be able to use defined field values there.

    However, form controls are initialized in the InitializeComponent() method called at the end of the constructor. Therefore, at the time the MAP variable is initialized, the Foo and Bar member variables exist, but they are not yet initialized to refer to the actual control objects they are intended to represent.

    To fix this, you need to change the code so items are added to the MAP collection after the InitializeComponent() method runs.