?
Solved

help with simple class

Posted on 2006-07-11
15
Medium Priority
?
193 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 400 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 52

Assisted Solution

by:Carl Tawn
Carl Tawn earned 400 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
 
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 63

Accepted Solution

by:
Fernando Soto earned 1200 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 63

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 63

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 Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: Kraeven
Introduction Remote Share is a simple remote sharing tool, enabling you to see, add and remove remote or local shares. The application is written in VB.NET targeting the .NET framework 2.0. The source code and the compiled programs have been in…
It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

764 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