• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 196
  • Last Modified:

help with simple class

Others have been trying to help me with what for me is a complex problem in a class (I'm new to .Net!)

So I created these two very simple classes based on that information.  These are supposed to work together to return an array to the GUI

Public Class MyTestClass
    Private mData As ArrayList
    Private mIndex As Integer

    Public Property Data() As ArrayList
        Get
            Return mData
        End Get
        Set(ByVal Value As ArrayList)
            mData = Value
        End Set
    End Property

    Public Property Index() As Integer
        Get
            Return mIndex
        End Get
        Set(ByVal Value As Integer)
            mIndex = Value
        End Set
    End Property

    Public Sub setValues()
        Dim rec As New HoldReturnValues

        rec.rName = "me"
        rec.rAge = 25
        mData.Add(rec)
        rec.rName = "myWife"
        rec.rAge = 200
        mData.Add(rec)
        mIndex = 0
    End Sub

    Public Function getRecord() As HoldReturnValues
        If mIndex <= mData.Count - 1 AndAlso mIndex > 0 Then
            Return CType(mData(mIndex), HoldReturnValues)
            mIndex = mIndex + 1
        Else
            Return Nothing
        End If
    End Function
End Class

Public Class HoldReturnValues
    Public rName As String
    Public rAge As Integer
End Class

The code in the GUI looks like this:

        Dim obj As New ClassTest.MyTestClass
        Dim record As ClassTest.HoldReturnValues = obj.getRecord <========== gets an error right here

        While Not record Is Nothing
            ListBox1.Items.Add(record.rName & " " & record.rAge.ToString)
        End While

The error is:
An unhandled exception of the type 'System.NullReferenceException' occured in the ClassTest.dll

Additional Information:  Object reference not set to an instance of the object.

In the dll, the line that throws the error is this one:
        If mIndex <= mData.Count - 1 AndAlso mIndex > 0 Then


1.  What the heck am I doing wrong?
2.  What is EVER going to call the setValues subroutine?
0
g_johnson
Asked:
g_johnson
  • 6
  • 4
  • 3
  • +1
3 Solutions
 
Carl TawnSystems and Integration DeveloperCommented:
1) HoldReturnValues is a seperate class, it is not part of ClassTest. So you simply need:

    Dim record As HoldReturnValues = obj.getRecord()

2) You either need to call setValues() directly, or maybe from the constructor.
0
 
ptakjaCommented:
The problem is that you are trying to get an item from  your arraylist but you never actually created the arraylist object. .NET is 100% object oriented. That means that in order to utilize an object, you must first ensure that it has been instantiated (ie., created).

To fix your issue, try this:

Public Class MyTestClass
    Private mData As ArrayList
    Private mIndex As Integer

' --------- NEW CODE HERE -----------
  ' Create a Class constructor. This method gets called when you create a new instance of your MyTestClass object. Inside here we initialize any objects
  ' that our class will use.
   Public Sub New()
       mData = New ArrayList
   End Sub

    Public Property Data() As ArrayList
        Get
            Return mData
        End Get
        Set(ByVal Value As ArrayList)
            mData = Value
        End Set
    End Property

    Public Property Index() As Integer
        Get
            Return mIndex
        End Get
        Set(ByVal Value As Integer)
            mIndex = Value
        End Set
    End Property

    Public Sub setValues()
        Dim rec As New HoldReturnValues

        rec.rName = "me"
        rec.rAge = 25
        mData.Add(rec)
        rec.rName = "myWife"
        rec.rAge = 200
        mData.Add(rec)
        mIndex = 0
    End Sub

    Public Function getRecord() As HoldReturnValues
        If mIndex <= mData.Count - 1 AndAlso mIndex > 0 Then
            Return CType(mData(mIndex), HoldReturnValues)
            mIndex = mIndex + 1
        Else
            Return Nothing
        End If
    End Function
End Class
0
 
g_johnsonAuthor Commented:
ptkaja -- that solved the error.  Thanks!

But now I get no data, so my next question is:
from carl_tawn (hey!  weren't you helping me before!  LOL)
2) You either need to call setValues() directly, or maybe from the constructor.

How do I call it directly?  From where?  I really don't want it in the constructor because this class will eventually be used to insert, update, and delete records into a database as well as to read them from it.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Carl TawnSystems and Integration DeveloperCommented:
You call it from wherever is right for your application. Its difficult to be more clear than that as it depends on how your application needs to work.

If you wanted to you could call it immediatley after you create the object:

    Dim obj As New ClassTest.MyTestClass()
    obj.setValues()

    '// Rest of your code to handle each record
0
 
ptakjaCommented:
I agree with carl_tawn. Now you have an initialized class but you never stuff any data in it. That's why when you go to get data out, you don't get anything.

First off, I would modify the SetValues routine as follows:

    Public Sub setValues(ByVal Name As String, ByVal Age As Integer)
        Dim rec As New HoldReturnValues

        rec.rName = Name
        rec.rAge = Age
        mData.Add(rec)

    End Sub

In your GUI code do something like this:

        Dim obj As New ClassTest.MyTestClass

       Call obj.SetValues("Me", 39)
       Call obj.SetValues("MyWife", 40)

Now you have some data...


 
0
 
g_johnsonAuthor Commented:
Eventually this setValues routine will be used to read a database, so I don't want to pass it values, I want it to generate values into the array.  Based on carl_tawn's suggestion I modified the GUI like this:

        Dim obj As New ClassTest.MyTestClass
        obj.setValues()
        Dim record As ClassTest.HoldReturnValues = obj.getRecord


        While Not record Is Nothing
            ListBox1.Items.Add(record.rName & " " & record.rAge.ToString)
        End While

"record" is still "nothing"

Thanks for your patience -- I know I'll eventually get this!
0
 
Carl TawnSystems and Integration DeveloperCommented:
Change this:

    If mIndex <= mData.Count - 1 AndAlso mIndex > 0 Then

To:

    If mIndex <= mData.Count - 1 Then

The value defaults to 0 and the indexes for the ArrayList start at zero. So if you also check that mIndex > 0 you will never get anything.
0
 
g_johnsonAuthor Commented:
yep, I stumbled upon that and now it's returning a value, BUT

1.  mIndex is 0 when I first hit the getRecord routine
2.  the GUI receives "myWife" which is actually index 1, I think
3.  the GUI is in an infinite loop, returning "myWife" over and over again
0
 
Fernando SotoCommented:
Hi g_johnson;

I went through your code and made comments.

    Public Class MyTestClass

        ' Need to add the New Keyword to create an instance of the ArrayList
        ' Without the New keyword you only create a variable that can point to
        ' an object of ArrayList.
        Private mData As New ArrayList
        Private mIndex As Integer

        Public Property Data() As ArrayList
            Get
                Return mData
            End Get
            Set(ByVal Value As ArrayList)
                mData = Value
            End Set
        End Property

        Public Property Index() As Integer
            Get
                Return mIndex
            End Get
            Set(ByVal Value As Integer)
                mIndex = Value
            End Set
        End Property

        Public Sub setValues()
            Dim rec As New HoldReturnValues

            rec.rName = "me"
            rec.rAge = 25
            mData.Add(rec)
            rec.rName = "myWife"
            rec.rAge = 200
            mData.Add(rec)
            mIndex = 0
        End Sub

        Public Function getRecord() As HoldReturnValues
            ' Arrays are zero index base so the AndAlso needs to take that
            ' into account >= and not just > otherwise you will miss the
            ' first element.
            If mIndex <= mData.Count - 1 AndAlso mIndex >= 0 Then
                ' Any statement after the Return statement will not get executed
                ' So first assign the object to a variable then do the add 1 to
                ' mIndex and then Return.
                Dim Hrv As HoldReturnValues = CType(mData(mIndex), HoldReturnValues)
                'Return CType(mData(mIndex), HoldReturnValues)
                mIndex = mIndex + 1
                Return Hrv
            Else
                Return Nothing
            End If
        End Function

    End Class

    Public Class HoldReturnValues
        Public rName As String
        Public rAge As Integer
    End Class

===========================

        Dim obj As New ClassTest.MyTestClass
        obj.setValues()
        Dim record As ClassTest.HoldReturnValues = obj.getRecord

        ' You have created an endless loop here. The object record only has
        ' one object in it and not an array of HoldReturnValues.
        'While Not record Is Nothing
            ListBox1.Items.Add(record.rName & " " & record.rAge.ToString)
        'End While

Fernando
0
 
g_johnsonAuthor Commented:
[       ' You have created an endless loop here. The object record only has
        ' one object in it and not an array of HoldReturnValues.
        'While Not record Is Nothing
            ListBox1.Items.Add(record.rName & " " & record.rAge.ToString)
        'End While
]

You are correct.  So all that it is returning is the last "record" added by setValues.  How do I access all the other records?
0
 
Carl TawnSystems and Integration DeveloperCommented:
The reason you are only getting one record is because HoldReturnValues is a reference type. You need to create a new one for each item you add to the ArrayList:

    Public Sub setValues()
        Dim rec As New HoldReturnValues
        rec.rName = "me"
        rec.rAge = 25
        mData.Add(rec)

        rec = New HoldReturnValues
        rec.rName = "myWife"
        rec.rAge = 200
        mData.Add(rec)
        mIndex = 0
    End Sub
0
 
Fernando SotoCommented:
This is one way

        For Each rec As ClassTest.HoldReturnValues In obj.Data
            ListBox1.Items.Add(record.rName & " " & record.rAge.ToString)
        Next

Fernando
0
 
Fernando SotoCommented:
Sorry that should have been the following code.

        For Each rec As ClassTest.HoldReturnValues In obj.Data
            ListBox1.Items.Add(rec.rName & " " & rec.rAge.ToString)
        Next
0
 
g_johnsonAuthor Commented:
[This is one way

        For Each rec As ClassTest.HoldReturnValues In obj.Data
            ListBox1.Items.Add(record.rName & " " & record.rAge.ToString)
        Next

Fernando]

This got me really close!  Now I am getting two items in my list box, but they are the same item, i.e., the first record "me"

getRecord now looks like this:

    Public Function getRecord() As HoldReturnValues
        If mIndex <= mData.Count - 1 Then
            Dim Hrv As HoldReturnValues = CType(mData(mIndex), HoldReturnValues)
            mIndex += 1
            Return Hrv
        Else
            Return Nothing
        End If
    End Function
0
 
g_johnsonAuthor Commented:
[Sorry that should have been the following code.

        For Each rec As ClassTest.HoldReturnValues In obj.Data
            ListBox1.Items.Add(rec.rName & " " & rec.rAge.ToString)
        Next
]

Success!  Thank you all!

I can now study this some more and understand it and build on it.

Thanks very much!
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 4
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now