Jim Thio Jim Thio - 1 year ago 50
Vb.net Question

Why doesn't static works as expected in this lazy loading code?

The code is simple. It lazy loads a dictionary. If the dictionary is nothing then it fills the dictionary.

However, when I go through the program the code inside

If _countryDictionary Is Nothing Then
is called several times. I wonder what went wrong?

Static _countryDictionary As Generic.Dictionary(Of String, String)

If _countryDictionary Is Nothing Then
_countryDictionary = New Generic.Dictionary(Of String, String)

Dim listOfCountries = fileToCol(COUNTRYCODESFileName)

For Each var In listOfCountries
Dim ar = var.Split({"*"}, System.StringSplitOptions.None).ToList()
_countryDictionary.Add(LCase(ar(0)), UCase(ar(1)))
_countryDictionary.Add("delete", "de")
_countryDictionary.Add("default", "df")
_countryDictionary.Add("pakinmay", "py")

End If

Return _countryDictionary(country)
End Get

enter image description here
Here is a screenshot of my debugging. As you see it's still nothing. Does static keywords work differently on get method in vb.net?

Update: Based on the answer, it seems that the static variable here is different for different instance of the class. I always thought the word static means the variable is not in the heap but in the stack or in the code portion. I guess I am wrong.

Answer Source

As @Mark pointed in his comment and documents, Static keyword define a variable shared between different calls to the procedure where static variable is defined (Getter in your case)

Public Class Test

    Public ReadOnly Property Value As Integer
            Static SomeConstant As Integer = 0
            SomeConstant += 1
            Return SomeConstant
        End Get
    End Property

End Class

Sub Main()

  Dim test1 As New Test()
  Console.WriteLine(test1 .Value) 'Print 1
  Console.WriteLine(test1 .Value) 'Print 2

  Dim another As New Test()
  Console.WriteLine(another.Value) 'Print 1
  Console.WriteLine(another.Value) 'Print 2

End Sub

So in your case getter countryCode is executed from different instances of your class.

If you want to share instance between all instances of your class, then create static member by using keyword Shared

Public Class YourClass

    Private Shared ReadOnly CountryDictionary As Dictionary(Of String, String)

    Public ReadOnly Property CountryCode As String
            Return YourClass.CountryDictionary("country")
        End Get
    End Property

End Class

Then use it in same way as you have used _countryDictionary variable