Использование конструкторов и деструкторов

Обновлен: Ноябрь 2007

Конструкторы и деструкторы контролируют создание и удаление объектов.

Конструкторы

Чтобы создать конструктор для класса, нужно создать процедуру Sub New в любом месте в определении класса. Для создания конструктора с параметрами нужно задать имена и типы данных аргументов для Sub New аналогично назначению аргументов для любой другой процедуры, как в следующем примере:

Sub New(ByVal s As String)

Конструкторы часто перегружаются, как в следующем примере.

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

При определении класса, производного от другого класса, первая строка конструктора должна являться вызовом конструктора базового класса, если только базовый класс не имеет доступный конструктор, не использующий параметры. Пример вызова базового класса, содержащего вышеупомянутый конструктор: MyBase.New(s). В противном случае MyBase.New является необязательным и среда выполнения Visual Basic вызывает его неявно.

После написания кода для вызова конструктора родительского объекта можно добавить любой дополнительной код инициализации к процедуре Sub New. Sub New может принимать аргументы при вызове в качестве параметризованного конструктора. Эти параметры передаются из процедуры, вызывающей конструктор. Например, Dim AnObject As New ThisClass(X).

Деструкторы

В следующем коде показано использование Dispose и Finalize для освобождения ресурсов в базовом классе.

2z08e49e.alert_note(ru-ru,VS.90).gifПримечание.

Следует придерживаться рекомендаций по реализации IDisposable, описанным в Время существования: создание и уничтожение объектов.

    ' 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

В следующем коде показано использование Dispose и Finalize для освобождения ресурсов в производном классе.

' 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

В следующем коде показан общий шаблон разработки деструктора Dispose с помощью блока Using и эквивалентного блока Try...Finally.

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

В следующем примере объект создается с использованием конструктора с параметрами, после чего вызывается деструктор, если объект больше не нужен.

2z08e49e.alert_note(ru-ru,VS.90).gifПримечание.

Хотя в этом примере используется Collect для демонстрации методов, используемых сборщиком мусора для удаления методов, обычно управление сборкой мусора следует передать среде выполнения (CLR).

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

При запуске этого примера класс ThisClass вызывает конструктор Sub New класса BaseClass. После завершения конструктора в базовом классе класс ThisClass запускает остальные операторы в Sub New, который инициализирует значение свойства ThisProperty.

Когда в классе больше нет необходимости, деструктор Dispose вызывается в ThisClass.

Этот код выводит следующие данные.

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.

См. также

Основные понятия

Время существования: создание и уничтожение объектов

Методы "Finalize" и деструкторы

Работа методов New и Finalize в иерархии классов

Ссылки

Dispose