views:

652

answers:

2

Stack Overflowers:

I have been racking my brain trying to get an List(of T) type array to be the property of a class. I know there has to be a simple way of doing it and I can't find a good example on google. Everytime I create a class that I think will work I get the "Object reference not set to an instance of an object" error when I try to use it. My thinking now is that I cannot use it in the way I was hoping to. Here is my latest attempt:

Public Class Item
    Private _itemno As String
    Public Property ItemNo() As String
        Get
            Return _itemno
        End Get
        Set(ByVal value As String)
            _itemno = value
        End Set
    End Property
        //Many more properties in here
End Class


Public Class Accessory
    Private _items as List(of Item)
    Public Property Items() As List(of Item)
        Get
            Return _itemno
        End Get
        Set(ByVal value As List(of Item))
            _itemno = value
        End Set
    End Property
End Class

Public Class MasterItem
    Private _item as Item
    Public Property PrimaryItem as Item
        Get
            Return _item
        End Get
        Set(ByVal value As Item)
            _item = value
        End Set
    End Property

    Private _accessories as Accessory
    Public Property Accessories() As Accessory
        Get
            Return _accessories
        End Get
        Set(ByVal value As Accessory)
            _accessories = value
        End Set
    End Property
End Class

I am trying to return the MasterItem class from a test function like this:

Public Shared Function GetItem() as MasterItem
    Dim testItem as new MasterItem

    ReturnItem.PrimaryItem.ItemNo = "TEST123"

    ReturnItem.Accessories.Items.add(New Item("TESTACC1"))
    ReturnItem.Accessories.Items.add(New Item("TESTACC2"))

    Return testItem
End Function

What am I doing wrong here? Thanks in advance.

+5  A: 

You haven't create an instance of list you are trying to put items to.

Initialize it in constructor of your Accessory class. Something like

Public Sub New()
    _items = New List(Of Item)
End Sub
elder_george
A: 

You have 2 options to avoid the NullReferenceException:

1) The approach elder_george mentioned, where you initialize the property to a new instance of the class:

Dim ReturnItem As New MasterItem
ReturnItem.PrimaryItem = New Item()
' or check for null then initialize (optional, depends on your needs)
If ReturnItem.PrimaryItem Is Nothing Then ReturnItem.PrimaryItem = New Item()

The problem with this approach is if you don't initialize it somewhere that you know it will always be valid to use later, you'll have to do the same check and/or initialize. That "somewhere" might be on a form load or such.

2) Initialize the property's backing store variable. Do this once and you don't need to check for null all the time. Notice the change in the _item declaration below:

Public Class MasterItem
    Private _item as Item = New Item()
    Public Property PrimaryItem as Item
     Get
      Return _item
     End Get
     Set(ByVal value As Item)
      _item = value
     End Set
    End Property
End Class

With the above in place, you would access it directly as:

Dim ReturnItem As New MasterItem
ReturnItem.PrimaryItem.ItemNo = "TEST123"
Ahmad Mageed
I knew it was something simple I just kept overlooking. Option #2 will fit my situation perfectly. Thanks.
NinjaBomb
Changed my accespted answer to elder_george's post after doing some added research and testing both suggestions.
NinjaBomb