Using Constructors and Destructors

Constructors and destructors control the creation and destruction of objects.

Constructors

To create a constructor for a class, create a procedure named Sub New anywhere in the class definition. To create a parameterized constructor, specify the names and data types of arguments to Sub New just as you would specify arguments for any other procedure, as in the following code:

Sub New(ByVal s As String)

Constructors are frequently overloaded, as in the following code:

Sub New(ByVal s As String, i As Integer)

When you define a class derived from another class, the first line of a constructor must be a call to the constructor of the base class, unless the base class has an accessible constructor that takes no parameters. A call to the base class that contains the above constructor, for example, would be MyBase.New(s). Otherwise, MyBase.New is optional, and the Visual Basic runtime calls it implicitly.

After you write the code to call the parent object's constructor, you can add any additional initialization code to the Sub New procedure. Sub New can accept arguments when called as a parameterized constructor. These parameters are passed from the procedure calling the constructor, for example, Dim AnObject As New ThisClass(X).

Destructors

The following code shows how to use Dispose and Finalize to release resources in a base class.

Note

You should follow the guidelines for implementing IDisposable set out in Object Lifetime: How Objects Are Created and Destroyed.

    ' Design pattern for a base class. 
    Public Class Base
        Implements IDisposable

        ' Keep track of when the object is disposed. 
        Protected disposed As Boolean = False 

        ' This method disposes the base object's resources. 
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposed Then 
                If disposing Then 
                    ' Insert code to free managed resources. 
                End If 
                ' Insert code to free unmanaged resources. 
            End If 
            Me.disposed = True 
        End Sub

#Region " IDisposable Support " 
        ' Do not change or add Overridable to these methods. 
        ' Put cleanup code in Dispose(ByVal disposing As Boolean). 
        Public Sub Dispose() Implements IDisposable.Dispose
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub 
        Protected Overrides Sub Finalize()
            Dispose(False)
            MyBase.Finalize()
        End Sub
#End Region
    End Class

The following code shows how to use Dispose and Finalize to release resources in a derived class.

' Design pattern for a derived class. 
Public Class Derived
    Inherits Base

    ' This method disposes the derived object's resources. 
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If Not Me.disposed Then 
            If disposing Then 
                ' Insert code to free managed resources. 
            End If 
            ' Insert code to free unmanaged resources. 
        End If 
        MyBase.Dispose(disposing)
    End Sub 

    ' The derived class does not have a Finalize method 
    ' or a Dispose method with parameters because it inherits 
    ' them from the base class. 
End Class

The following code shows a common design pattern for the Dispose destructor, using a Using block and an equivalent Try...Finally block.

Sub DemonstrateUsing()
    Using d As New Derived
        ' Code to use the Derived object goes here. 
    End Using 
End Sub 

Sub DemonstrateTry()
    Dim d As Derived = Nothing 
    Try
        d = New Derived
        ' Code to use the Derived object goes here. 
    Finally 
        ' Call the Dispose method when done, even if there is an exception. 
        If Not d Is Nothing Then
            d.Dispose()
        End If 
    End Try 
End Sub

The next example creates an object by using a parameterized constructor, and then calls destructors when the object is no longer needed.

Note

Although this example uses Collect to demonstrate which methods the garbage collector calls to dispose methods, in general you should let the common language runtime (CLR) manage garbage collection.

Sub TestConstructorsAndDestructors()
    ' Demonstrate how the Using statement calls the Dispose method. 
    Using AnObject As New ThisClass(6)
        ' Place statements here that use the object.
        MsgBox("The value of ThisProperty after being initialized " & _
        " by the constructor is " & AnObject.ThisProperty & ".")
    End Using 

    ' Demonstrate how the garbage collector calls the Finalize method. 
    Dim AnObject2 As New ThisClass(6)
    AnObject2 = Nothing
    GC.Collect()
End Sub 

Public Class BaseClass
    Sub New()
        MsgBox("BaseClass is initializing with Sub New.")
    End Sub 

    Protected Overrides Sub Finalize()
        MsgBox("BaseClass is shutting down with Sub Finalize.")
        ' Place final cleanup tasks here. 
        MyBase.Finalize()
    End Sub 
End Class 

Public Class ThisClass
    Inherits BaseClass
    Implements IDisposable

    Sub New(ByVal SomeValue As Integer)
        ' Call MyBase.New if this is a derived class. 
        MyBase.New()
        MsgBox("ThisClass is initializing with Sub New.")
        ' Place initialization statements here. 
        ThisPropertyValue = SomeValue
    End Sub 

    Private ThisPropertyValue As Integer 
    Property ThisProperty() As Integer 
        Get
            CheckIfDisposed()
            ThisProperty = ThisPropertyValue
        End Get 
        Set(ByVal Value As Integer)
            CheckIfDisposed()
            ThisPropertyValue = Value
        End Set 
    End Property 

    Protected Overrides Sub Finalize()
        MsgBox("ThisClass is shutting down with Sub Finalize.")
        Dispose(False)
    End Sub 

    ' Do not add Overridable to this method. 
    Public Overloads Sub Dispose() Implements IDisposable.Dispose
        MsgBox("ThisClass is shutting down with Sub Dispose.")
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub 

    Private disposed As Boolean = False 
    Public Sub CheckIfDisposed()
        If Me.disposed Then 
            Throw New ObjectDisposedException(Me.GetType().ToString, _
            "This object has been disposed.")
        End If 
    End Sub 

    Protected Overridable Overloads Sub Dispose( _
    ByVal disposing As Boolean)
        MsgBox("ThisClass is shutting down with the Sub Dispose overload.")
        ' Place final cleanup tasks here. 
        If Not Me.disposed Then 
            If disposing Then 
                ' Dispose of any managed resources. 
            End If 
            ' Dispose of any unmanaged resource. 

            ' Call MyBase.Finalize if this is a derived class,  
            ' and the base class does not implement Dispose. 
            MyBase.Finalize()
        End If 
        Me.disposed = True 
    End Sub 

End Class

When you run this example, the class ThisClass calls the Sub New constructor of the class BaseClass. After the constructor in the base class is finished, the class ThisClass runs the remaining statements in Sub New that initialize a value for the property ThisProperty.

When the class is no longer needed, the Dispose destructor is called in ThisClass.

This example displays the following:

BaseClass is initializing with Sub New.

ThisClass is initializing with Sub New.

The value of ThisProperty after being initialized by the constructor is 6.

ThisClass is shutting down with Sub Dispose.

ThisClass is shutting down with the Sub Dispose overload.

BaseClass is shutting down with Sub Finalize.

BaseClass is initializing with Sub New.

ThisClass is initializing with Sub New.

ThisClass is shutting down with Sub Finalize.

ThisClass is shutting down with the Sub Dispose overload.

BaseClass is shutting down with Sub Finalize.

See Also

Concepts

Object Lifetime: How Objects Are Created and Destroyed

Finalize Methods and Destructors

How New and Finalize Methods Work in a Class Hierarchy

Reference

Dispose