Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Eine Instanz einer Klasse, eines Objekts, wird mithilfe des New
Schlüsselworts erstellt. Initialisierungsaufgaben müssen häufig für neue Objekte ausgeführt werden, bevor sie verwendet werden. Allgemeine Initialisierungsaufgaben umfassen das Öffnen von Dateien, das Herstellen einer Verbindung mit Datenbanken und das Lesen von Werten von Registrierungsschlüsseln. Visual Basic steuert die Initialisierung neuer Objekte mithilfe von Prozeduren, die als Konstruktoren bezeichnet werden (spezielle Methoden, die die Kontrolle über die Initialisierung ermöglichen).
Nachdem ein Objekt den Bereich verlässt, wird es von der Common Language Runtime (CLR) freigegeben. Visual Basic steuert die Veröffentlichung von Systemressourcen mithilfe von Prozeduren, die als Destruktoren bezeichnet werden. Zusammen unterstützen Konstruktoren und Destruktoren die Erstellung robuster und vorhersagbarer Klassenbibliotheken.
Verwenden von Konstruktoren und Destruktoren
Konstruktoren und Destruktoren steuern die Erstellung und Zerstörung von Objekten. Die Sub New
und Sub Finalize
Prozeduren in Visual Basic initialisieren und zerstören Objekte; sie ersetzen die in Visual Basic 6.0 und früheren Versionen verwendeten Class_Initialize
und Class_Terminate
Methoden.
Unter Neu
Der Sub New
Konstruktor kann nur einmal ausgeführt werden, wenn eine Klasse erstellt wird. Sie kann nicht explizit an einer anderen Stelle als in der ersten Codezeile eines anderen Konstruktors aus derselben Klasse oder aus einer abgeleiteten Klasse aufgerufen werden. Darüber hinaus wird der Code in der Sub New
Methode immer vor einem anderen Code in einer Klasse ausgeführt. Visual Basic erstellt implizit zur Laufzeit einen Sub New
Konstruktor, wenn Sie keine Sub New
Prozedur für eine Klasse explizit definieren.
Um einen Konstruktor für eine Klasse zu erstellen, erstellen Sie eine Prozedur, die an einer beliebigen Stelle in der Klassendefinition benannt ist Sub New
. Um einen parametrisierten Konstruktor zu erstellen, geben Sie die Namen und Datentypen von Argumenten Sub New
genauso an, wie Sie Argumente für eine andere Prozedur angeben würden, wie im folgenden Code:
Sub New(ByVal s As String)
Konstruktoren werden häufig überladen, wie im folgenden Code:
Sub New(ByVal s As String, i As Integer)
Wenn Sie eine von einer anderen Klasse abgeleitete Klasse definieren, muss die erste Zeile eines Konstruktors ein Aufruf des Konstruktors der Basisklasse sein, es sei denn, die Basisklasse verfügt über einen barrierefreien Konstruktor, der keine Parameter akzeptiert. Ein Aufruf der Basisklasse, die den obigen Konstruktor enthält, wäre beispielsweise MyBase.New(s)
.
MyBase.New
Andernfalls ist dies optional, und die Visual Basic-Laufzeit ruft sie implizit auf.
Nachdem Sie den Code zum Aufrufen des Konstruktors des übergeordneten Objekts geschrieben haben, können Sie der Sub New
Prozedur zusätzlichen Initialisierungscode hinzufügen.
Sub New
kann Argumente akzeptieren, wenn sie als parametrisierter Konstruktor aufgerufen werden. Diese Parameter werden von der Prozedur übergeben, die den Konstruktor aufruft, wie zum Beispiel Dim AnObject As New ThisClass(X)
.
Sub Finalize
Vor dem Freigeben von Objekten ruft die CLR automatisch die Finalize
Methode für Objekte auf, die eine Sub Finalize
Prozedur definieren. Die Finalize
Methode kann Code enthalten, der unmittelbar vor dem Löschen eines Objekts ausgeführt werden muss, z. B. Code zum Schließen von Dateien und Speichern von Statusinformationen. Es gibt eine geringfügige Leistungseinbuße für die Ausführung Sub Finalize
. Daher sollten Sie eine Sub Finalize
Methode nur dann definieren, wenn Sie Objekte explizit freigeben müssen.
Hinweis
Der Garbage Collector in der CLR entsorgt nicht (und kann nicht entsorgen) nicht verwaltete Objekte, Objekte, die vom Betriebssystem direkt außerhalb der CLR-Umgebung ausgeführt werden. Dies liegt daran, dass verschiedene nicht verwaltete Objekte auf unterschiedliche Weise verworfen werden müssen. Diese Informationen sind nicht direkt mit dem nicht verwalteten Objekt verknüpft; sie muss in der Dokumentation für das Objekt gefunden werden. Eine Klasse, die nicht verwaltete Objekte verwendet, muss sie in ihrer Finalize
Methode löschen.
Der Finalize
Destruktor ist eine geschützte Methode, die nur von der Klasse aufgerufen werden kann, zu der sie gehört, oder von abgeleiteten Klassen. Das System ruft automatisch aufFinalize
, wenn ein Objekt zerstört wird. Daher sollten Sie nicht explizit von außerhalb der Implementierung einer abgeleiteten Klasse Finalize
aufrufenFinalize
.
Im Gegensatz dazu Class_Terminate
, was ausgeführt wird, sobald ein Objekt auf nichts festgelegt ist, besteht in der Regel eine Verzögerung zwischen dem Verlust des Bereichs eines Objekts und dem Aufruf des Finalize
Destruktors in Visual Basic. Visual Basic .NET ermöglicht eine zweite Art von Destruktor, IDisposable.Disposedie jederzeit explizit aufgerufen werden kann, um Ressourcen sofort freizugeben.
Hinweis
Ein Finalize
Destruktor sollte keine Ausnahmen auslösen, da sie von der Anwendung nicht behandelt werden können und zum Absturz der Anwendung führen können.
Wie Neue und Finalize-Methoden in einer Klassenhierarchie arbeiten
Immer wenn eine Instanz einer Klasse erstellt wird, versucht die Common Language Runtime (CLR), eine Prozedur mit dem Namen New
auszuführen, sofern sie in diesem Objekt vorhanden ist.
New
ist ein Prozedurtyp namens constructor
, der genutzt wird, um neue Objekte zu initialisieren, bevor irgendein anderer Code in einem Objekt ausgeführt wird. Ein New
Konstruktor kann verwendet werden, um Dateien zu öffnen, eine Verbindung mit Datenbanken herzustellen, Variablen zu initialisieren und alle anderen Aufgaben zu erledigen, die ausgeführt werden müssen, bevor ein Objekt verwendet werden kann.
Wenn eine Instanz einer abgeleiteten Klasse erstellt wird, wird der Sub New
Konstruktor der Basisklasse zuerst ausgeführt, gefolgt von Konstruktoren in abgeleiteten Klassen. Dies geschieht, da die erste Codezeile in einem Sub New
Konstruktor die Syntax MyBase.New()
verwendet, um den Konstruktor der Klasse direkt über sich selbst in der Klassenhierarchie aufzurufen. Der Sub New
Konstruktor wird dann für jede Klasse in der Klassenhierarchie aufgerufen, bis der Konstruktor für die Basisklasse erreicht ist. Zu diesem Zeitpunkt wird der Code im Konstruktor der Basisklasse ausgeführt, gefolgt vom Code in jedem Konstruktor aller abgeleiteten Klassen, und der Code in den am weitesten abgeleiteten Klassen wird zuletzt ausgeführt.
Wenn ein Objekt nicht mehr benötigt wird, ruft die CLR die Finalize Methode für dieses Objekt auf, bevor der Arbeitsspeicher freigegeben wird. Die Finalize-Methode wird als destructor
bezeichnet, da sie Bereinigungsaufgaben ausführt, wie das Speichern von Statusinformationen, das Schließen von Dateien und das Trennen von Verbindungen zu Datenbanken sowie andere Aufgaben, die vor dem Freigeben des Objekts ausgeführt werden müssen.
IDisposable-Schnittstelle
Klasseninstanzen steuern häufig Ressourcen, die nicht von der CLR verwaltet werden, z. B. Windows-Handles und Datenbankverbindungen. Diese Ressourcen müssen in der Finalize
-Methode der Klasse beseitigt werden, sodass sie freigegeben werden, wenn das Objekt vom Garbage Collector zerstört wird. Der Garbage Collector zerstört objekte jedoch nur, wenn der CLR mehr freien Arbeitsspeicher benötigt. Dies bedeutet, dass die Ressourcen möglicherweise erst freigegeben werden, lange nachdem das Objekt außerhalb des Gültigkeitsbereichs ist.
Zur Ergänzung der Garbagecollection können die Klassen einen Mechanismus für die aktive Verwaltung von Systemressourcen bereitstellen, wenn sie die IDisposable-Schnittstelle implementieren.
IDisposable verfügt über eine Methode, die Clients aufrufen sollten, Disposewenn sie mit einem Objekt fertig sind. Mit der Dispose Methode können Sie Ressourcen sofort freigeben und Aufgaben wie das Schließen von Dateien und Datenbankverbindungen ausführen. Im Gegensatz zum Finalize
-Destruktor wird die Dispose-Methode nicht automatisch aufgerufen. Clients einer Klasse müssen Dispose explizit aufrufen, wenn Ressourcen sofort freigegeben werden sollen.
Implementieren von IDisposable
Eine Klasse, die die IDisposable Schnittstelle implementiert, sollte diese Codeabschnitte enthalten:
Ein Feld zum Nachverfolgen, ob das Objekt entsorgt wurde.
Protected disposed As Boolean = False
Eine Überladung von der Dispose, die die Ressourcen der Klasse freigibt. Diese Methode sollte von den Dispose und
Finalize
Methoden der Basisklasse aufgerufen werden.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
Eine Implementierung von Dispose, die nur den folgenden Code enthält:
Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub
Eine Überschreibung der
Finalize
-Methode, die nur den folgenden Code enthält:Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub
Ableiten von einer Klasse, die IDisposable implementiert
Eine Klasse, die von einer Basisklasse abgeleitet wird, die die IDisposable Schnittstelle implementiert, muss keine der Basismethoden außer Kraft setzen, es sei denn, sie verwendet zusätzliche Ressourcen, die verworfen werden müssen. In diesem Fall sollte die abgeleitete Klasse die Methode der Basisklasse Dispose(disposing)
überschreiben, um die Ressourcen der abgeleiteten Klasse zu löschen. Diese Überschreibung muss die Methode der Basisklasse Dispose(disposing)
aufrufen.
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
Eine abgeleitete Klasse sollte die Methoden Dispose und Finalize
der Basisklasse nicht überschreiben. Wenn diese Methoden aus einer Instanz der abgeleiteten Klasse aufgerufen werden, ruft die Basisklassenimplementierung dieser Methoden die Überschreibung der Dispose(disposing)
-Methode auf.
Garbagecollection und der Finalize-Destruktor
.NET Framework verwendet das verweisverfolgenden Garbage Collection-System, um nicht verwendete Ressourcen in regelmäßigen Abständen freizugeben. Visual Basic 6.0 und frühere Versionen verwendeten ein anderes System, das als Verweiszählung bezeichnet wird, um Ressourcen zu verwalten. Obwohl beide Systeme die gleiche Funktion automatisch ausführen, gibt es einige wichtige Unterschiede.
Die CLR zerstört in regelmäßigen Abständen Objekte, wenn das System feststellt, dass solche Objekte nicht mehr benötigt werden. Objekte werden schneller freigegeben, wenn die Systemressourcen knapp sind, und ansonsten seltener. Die Verzögerung zwischen dem Verlust des Gültigkeitsbereichs eines Objekts und der Veröffentlichung der CLR bedeutet, dass Sie im Gegensatz zu Objekten in Visual Basic 6.0 und früheren Versionen nicht genau bestimmen können, wann das Objekt zerstört wird. In einer solchen Situation sollen Objekte nicht deterministische Lebenszeit haben. In den meisten Fällen ändert die nicht-deterministische Lebensdauer nicht, wie Sie Anwendungen schreiben, solange Sie daran denken, dass der Destruktor möglicherweise nicht sofort ausgeführt wird, wenn ein Objekt den Finalize
Gültigkeitsbereich verliert.
Ein weiterer Unterschied zwischen den Müllsammelsystemen betrifft die Verwendung von Nothing
. Um die Referenzzählung in Visual Basic 6.0 und früheren Versionen zu nutzen, wiesen Programmierer manchmal Nothing
Objektvariablen zu, um die Verweise freizugeben, die diese Variablen hielten. Wenn die Variable den letzten Verweis auf das Objekt gehalten hat, wurden die Ressourcen des Objekts sofort freigegeben. In späteren Versionen von Visual Basic kann es fälle geben, in denen dieses Verfahren weiterhin nützlich ist, dies führt jedoch nie dazu, dass das referenzierte Objekt seine Ressourcen sofort freigibt. Um Ressourcen sofort freizugeben, verwenden Sie die Methode des Dispose Objekts, falls verfügbar. Die einzige Gelegenheit, eine Variable auf Nothing
zu setzen, ist, wenn ihre Lebensdauer im Verhältnis zu der Zeit, die der Garbage Collector benötigt, um verwaiste Objekte zu erkennen, lang ist.