0

I have a dictionary as one of the fields of the structure of the value part of another dictionary so that a course can contain multiple classes, each with its own teacher and students as below:

Structure course
    Dim description As String
    Structure classs
        Dim teacherCode As String
        Dim studentIDs() As Integer
    End Structure
    Dim classes As Dictionary(Of String, classs) 'key=classCode
End Structure

Structure courseKey
    Dim name As String
    Dim yearLevel As Short
End Structure

Dim courses As New Dictionary(Of courseKey, course)

I can construct a courseKey and create an empty courses dictionary entry using an empty classs sub-dictionary with courses.Add(courseKey, course), but I can't work out how (or, indeed, if it's possible) to create a new courses dictionary entry with a non-empty classs sub-dictionary. I expected to be able to do something like this to create a classs and then add it to the course, but get a NullReferenceException (even when courses(courseKey) references the appropriate dictionary item, and when classCode is a valid string and classs is a valid instance of the classs structure with data in it):

courses(courseKey).classes.Add(classCode, classs)

Am I missing something obvious? I was planning on having a few data structures like this, some with multiple dictionaries inside another dictionary. If this isn't possible, perhaps there's a better way?

  • 1
    What expression was null? Find out. I'm tempted to close this off as a duplicate of the canonical NRE question. I'm not seeing how this case is special. – usr Jul 23 '14 at 13:42

2 Answers2

3

NullReferenceException always means the same thing. In this case, you haven't instantiated the classes dictionary in your course structure.

Dim classes As Dictionary(Of String, classs) 'key=classCode

For comparison, you've instantiated the courses dictionary with the New keyword.

Dim courses As New Dictionary(Of courseKey, course)

Normally you would create your classes dictionary the same way, but in this case, it's in a structure, and you're not allowed to have a default constructor or member initializers in a structure.

You need to initialize your dictionary somewhere, so you have a few options. Probably the easiest would be to wrap it into a property:

Private _classes As Dictionary(Of String, [class])

Public ReadOnly Property Classes As Dictionary(Of String, [class])
    Get
        If _classes Is Nothing Then _classes = New Dictionary(Of String, [class])()
        Return _classes
    End Get
End Property

If your code is potentially multithreaded, you'd want to handle this differently, but that provides a Classes property on the course structure that will initialize its private backing member if it doesn't already exist.

(Incidentally, I changed the name classs to class and wrapped it in square brackets to escape the name.)

Community
  • 1
  • 1
pmcoltrane
  • 3,052
  • 1
  • 24
  • 30
1

Your classes dictionary inside the course class needs to be initialized. You can do this within a constructor:

Structure course

    ...

    Public Sub New(description As String)

        Me.description = description
        classes = New Dictionary(Of String, classs)

    End Sub

    ...

End Structure
MJVC
  • 497
  • 4
  • 7