Solved

help with simple class

Posted on 2006-07-11
15
187 Views
Last Modified: 2010-04-23
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
Comment
Question by:g_johnson
  • 6
  • 4
  • 3
  • +1
15 Comments
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 17082315
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
 
LVL 14

Assisted Solution

by:ptakja
ptakja earned 100 total points
ID: 17082332
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
 
LVL 4

Author Comment

by:g_johnson
ID: 17082450
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
 
LVL 52

Assisted Solution

by:Carl Tawn
Carl Tawn earned 100 total points
ID: 17082535
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
 
LVL 14

Expert Comment

by:ptakja
ID: 17082552
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
 
LVL 4

Author Comment

by:g_johnson
ID: 17082618
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
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 17082654
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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 4

Author Comment

by:g_johnson
ID: 17082688
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
 
LVL 62

Accepted Solution

by:
Fernando Soto earned 300 total points
ID: 17082698
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
 
LVL 4

Author Comment

by:g_johnson
ID: 17082734
[       ' 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
 
LVL 52

Expert Comment

by:Carl Tawn
ID: 17082781
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
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 17082823
This is one way

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

Fernando
0
 
LVL 62

Expert Comment

by:Fernando Soto
ID: 17082856
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
 
LVL 4

Author Comment

by:g_johnson
ID: 17082910
[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
 
LVL 4

Author Comment

by:g_johnson
ID: 17082937
[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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now