Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

VB.NET implicitly instantiating objects

Posted on 2004-08-11
1
Medium Priority
?
834 Views
Last Modified: 2008-02-01
I have a class Application, which has a collection containing Applicants attached to it.

In the property for the collection, I have the following:

Get
    If _Applicants is Nothing then
        _Applicants = new ObjectCollection
        LoadApplicants()
    End IF
End Get

Now, when I create an Application, I don't make any sort of reference to the Applicant collection, and immediately after the Application is created, in the Quick Watch window I can see that _Applicants is still nothing.  The problem starts in the loop below:

For each objApplicant in objApplication.Applicants
     ....do some stuff
Next

If I set a break point on the "for each" line, then use the watch to check, _Applicants has been instantiated.  However, because it hasn't gone through the property, the Applicants haven't been loaded and I never get inside the loop.

Is there anything I can do to stop .NET implicitly creating the Applicants collection, or force it to do so via the property?
0
Comment
Question by:racka
1 Comment
 
LVL 1

Accepted Solution

by:
IT Meetjesland earned 2000 total points
ID: 11781591
I don't know why you're using ObjectCollection.  But that doesn't really matter for the problem you have.  The reason why your Applicants property in the For Each loop is not properly loaded is because of the fact that it WAS loaded but you didn't return the reference to it.  Your Getter of property Applicants should be:

Get
    If IsNothing(_Applicants) Then
        _Applicants = new ObjectCollection
        LoadApplicants()
    End If
    Return _Applicants
End Get

Anyway.  I tried a little test with the code that i pasted below and it works just fine.  I do it with a Collection instead of ObjectCollection because I don't see an advantage in using the latter, but it really doesn't matter which Collection class you use.

I made a new VB.NET Windows Application in VS.NET 2003 and in the Main form code i have put following:

Public Class Form1
    Inherits System.Windows.Forms.Form

' here comes the #Region " Windows Form Designer generated code " which i'm not posting for obvious reasons

#Region "Event Handlers"

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim app As New Application
        For Each Applic As Applicant In app.Applicants
            MessageBox.Show(Applic.ToString())
        Next
    End Sub

#End Region

End Class

Public Class Application

    Protected _Applicants As Collection

    Protected Overridable Sub LoadApplicants()
        For I As Integer = 0 To 4
            _Applicants.Add(New Applicant)
        Next
    End Sub

    Public Overridable ReadOnly Property Applicants() As Collection
        Get
            If _Applicants Is Nothing Then
                _Applicants = New Collection
                LoadApplicants()
            End If
            Return _Applicants
        End Get
    End Property

End Class

Public Class Applicant

    'empty class, just to demonstrate the Collection problem.

    Public Overrides Function ToString() As String
        Return "This is an Applicant"
    End Function

End Class

And to finish, some tips:
  * Better replace the identifier of class Application by another one because Application is a class of the .NET framework (namespace System) and you may get ambiguous identifier problems sooner or later.
  * Using method IsNothing() is better than comparing an object to Nothing because of the idealistic object oriented thought that checking whether an object is not instantiated could change in the future in which case it's easier to change it in the implementation of IsNothing() than change it EVERYWHERE in your code where you wrote If SomeObject is Nothing Then.
  * It is not advisable to add a lot of functionality to a property getter or setter.  Nobody (= other developers) ever will expect the property they use to do much more than what it's supposed to do: return a reference to the requested object.  So, the LoadApplicants() method call doesn't really belong in the getter.  In this case, I would create and load the collection in the constructor of the class, or even better: in an Initialize() method which is then called from the constructor or from outside the class.  The advantage of having a separate Initialize() method is that it can be stuffed with pure initialization code and can be called again and again later on.

With these things in mind, your class would look like:

Public Class ClsApplication

#Region "Fields"

    Protected _Applicants As Collection

#End Region

#Region "Constructors - Destructor"

    Public Sub New()
        _Applicants = New Collection
        ' Initialize other objects
        Initialize()
    End Sub

    Public Overridable Sub Dispose()
        _Applicants = Nothing
    End Sub

#End Region

#Region "Methods"

    Protected Overridable Sub LoadApplicants(ByVal AApplicants As Collection)
        For I As Integer = 0 To 4
            AApplicants.Add(New Applicant)
        Next
    End Sub

    Public Overridable Sub Initialize()
        LoadApplicants(_Applicants)
    End Sub

#End Region

#Region "Properties"

    Public Overridable ReadOnly Property Applicants() As Collection
        Get
            Return _Applicants
        End Get
    End Property

#End Region

End Class


Hope this helps, Thomas V
0

Featured Post

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.

Question has a verified solution.

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

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Integration Management Part 2
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…

972 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