In Visual Basic is een constructor een Sub New-procedure die wordt aangeroepen bij het creëren van een instantie van een klasse en het initialiseren van het object. Een destructor wordt gerealiseerd met behulp van de Finalize-methode of de IDisposable-interface (Dispose-methode), wat vooral belangrijk is voor het vrijgeven van middelen.
In klassiek Visual Basic werd de constructor automatisch aangeroepen bij het creëren van objecten (Class_Initialize), en de destructor bij verwijdering (Class_Terminate). In VB.NET zijn er overbelaste constructors toegevoegd, met scheiding tussen het vrijgeven van beheerde en niet-beheerde middelen, en het gebruik van de garbage collector (GC).
Onjuist gebruik van constructors of destructors leidt tot geheugenlekken, onjuiste initialisatie van objecten of blokkering van middelen (bijvoorbeeld bestanden).
Gebruik Sub New voor het initialiseren van objecten, implementeer altijd Dispose voor expliciet vrijgeven van middelen. Als er een destructor (Finalize) wordt gebruikt, onthoud dan de latentie van GC en het onvermogen om het tijdstip van aanroep te voorspellen.
Voorbeeldcode:
Public Class ResourceHolder Implements IDisposable Private resource As SomeResource Public Sub New() resource = New SomeResource() Console.WriteLine("Hulpmiddel toegewezen") End Sub Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overridable Sub Dispose(disposing As Boolean) If disposing Then If resource IsNot Nothing Then resource.Release() resource = Nothing End If End If End Sub End Class
Kernpunten:
Kan de Sub New-constructor handmatig worden aangeroepen voor een al bestaand object?
Nee, de constructor wordt alleen aangeroepen bij het creëren van een object. Voor herinitialisatie moet een aparte Reset-methode of iets dergelijks worden gebruikt.
Wanneer wordt Finalize aangeroepen en is zijn uitvoering altijd gegarandeerd?
Finalize wordt aangeroepen door de garbage collector bij het vernietigen van een object, maar zijn uitvoering is niet gegarandeerd (bijvoorbeeld bij een plotselinge beëindiging van het proces of bij stroomuitval).
Waarom moet GC.SuppressFinalize binnen Dispose worden aangeroepen?
Dit voorkomt een herhaalde aanroep van Finalize voor een al handmatig vrijgegeven object, verhoogt de prestaties en voorkomt geheugenlekken.
In het project werd Dispose niet geïmplementeerd en verschillende bestanden bleven vergrendeld na afsluiting van de applicatie - middelen werden niet vrijgegeven totdat de garbage collector interageerde.
Voordelen:
Nadelen:
Implementatie van IDisposable en Dispose, gebruik van Using bij het werken met externe middelen. Alle bestanden worden correct gesloten en de applicatie werkt stabiel.
Voordelen:
Nadelen: