Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wystąpienie klasy , obiektu, jest tworzone przy użyciu słowa kluczowego New
. Zadania inicjowania często muszą być wykonywane na nowych obiektach przed ich zastosowaniem. Typowe zadania inicjowania obejmują otwieranie plików, łączenie się z bazami danych i odczytywanie wartości kluczy rejestru. Visual Basic steruje inicjowaniem nowych obiektów przy użyciu procedur nazywanych konstruktorami (specjalne metody, które umożliwiają kontrolę nad inicjowaniem).
Po opuszczeniu zakresu obiekt jest zwalniany przez środowisko uruchomieniowe języka wspólnego (CLR). Visual Basic steruje wydawaniem zasobów systemowych przy użyciu procedur nazywanych destruktorami. Razem konstruktory i destruktory wspierają tworzenie niezawodnych i przewidywalnych bibliotek klas.
Używanie konstruktorów i destruktorów
Konstruktory i destruktory kontrolują tworzenie i niszczenie obiektów. Procedury Sub New
i Sub Finalize
w Visual Basic inicjalizują i niszczą obiekty; zastępują metody Class_Initialize
i Class_Terminate
używane w Visual Basic 6.0 i starszych wersjach.
Sub New
Konstruktor Sub New
może działać tylko raz po utworzeniu klasy. Nie można go wywołać jawnie w dowolnym miejscu innym niż w pierwszym wierszu kodu innego konstruktora z tej samej klasy lub z klasy pochodnej. Ponadto kod w metodzie Sub New
zawsze jest uruchamiany przed jakimkolwiek innym kodem w klasie. Program Visual Basic niejawnie tworzy Sub New
konstruktor w czasie wykonywania, jeśli nie zdefiniujesz jawnie procedury Sub New
dla klasy.
Aby utworzyć konstruktor dla klasy, utwórz procedurę o nazwie Sub New
w dowolnym miejscu w definicji klasy. Aby utworzyć konstruktor sparametryzowany, określ nazwy i typy danych argumentów tak Sub New
samo jak argumenty dla każdej innej procedury, jak w poniższym kodzie:
Sub New(ByVal s As String)
Konstruktory są często przeciążone, jak w poniższym kodzie:
Sub New(ByVal s As String, i As Integer)
Podczas definiowania klasy pochodnej z innej klasy pierwszy wiersz konstruktora musi być wywołaniem konstruktora klasy bazowej, chyba że klasa bazowa ma dostępny konstruktor, który nie przyjmuje żadnych parametrów. Wywołanie do klasy bazowej, która na przykład zawiera powyższy konstruktor, wyglądałoby tak: MyBase.New(s)
. W przeciwnym razie MyBase.New
jest opcjonalny, a środowisko uruchomieniowe języka Visual Basic wywołuje go niejawnie.
Po zapisaniu kodu w celu wywołania konstruktora obiektu nadrzędnego można dodać do procedury dowolny dodatkowy kod inicjowania Sub New
.
Sub New
może akceptować argumenty, gdy są wywoływane jako konstruktor sparametryzowany. Te parametry są przekazywane z procedury wywołującej konstruktor, na przykład Dim AnObject As New ThisClass(X)
.
Finalizowanie podrzędne
Przed zwolnieniem obiektów clR automatycznie wywołuje metodę Finalize
dla obiektów, które definiują procedurę Sub Finalize
. Metoda Finalize
może zawierać kod, który musi zostać wykonany tuż przed zniszczeniem obiektu, na przykład kod do zamykania plików i zapisywania informacji o stanie. Istnieje niewielka utrata wydajności podczas wykonywania Sub Finalize
, dlatego należy zdefiniować metodę Sub Finalize
tylko wtedy, gdy jest potrzeba jawnego zwolnienia obiektów.
Uwaga / Notatka
Zbieracz śmieci w CLR nie usuwa (i nie może usuwać) niezarządzanych obiektów, które są wykonywane bezpośrednio przez system operacyjny, poza środowiskiem CLR. Dzieje się tak, ponieważ różne niezarządzane obiekty muszą być usuwane na różne sposoby. Te informacje nie są bezpośrednio skojarzone z niezarządzanym obiektem; należy je znaleźć w dokumentacji obiektu. Klasa, która używa niezarządzanych obiektów, musi usunąć je w swojej Finalize
metodzie.
Destruktor Finalize
to chroniona metoda, która może być wywoływana tylko z klasy, do której należy, lub z klas pochodnych. System wywołuje Finalize
automatycznie, gdy obiekt zostanie zniszczony, dlatego nie należy jawnie wywoływać Finalize
z zewnątrz implementacji klasy pochodnej Finalize
.
W przeciwieństwie do metody Class_Terminate
, która wykonywana jest natychmiast po ustawieniu obiektu na wartość nic, zwykle występuje opóźnienie między utratą zakresu a wywołaniem destruktora Finalize
w języku Visual Basic. Program Visual Basic .NET umożliwia drugi rodzaj destruktora, IDisposable.Disposektóry można jawnie wywołać w dowolnym momencie, aby natychmiast zwolnić zasoby.
Uwaga / Notatka
Destruktor Finalize
nie powinien zgłaszać wyjątków, ponieważ nie można ich obsłużyć przez aplikację i może spowodować zakończenie działania aplikacji.
Jak działają metody 'new' i 'finalize' w hierarchii klas
Za każdym razem, gdy wystąpienie klasy jest tworzone, środowisko uruchomieniowe języka wspólnego (CLR) próbuje wykonać procedurę o nazwie New
, jeśli istnieje w tym obiekcie.
New
jest typem procedury nazywanej constructor
, która służy do inicjowania nowych obiektów przed wykonaniem jakiegokolwiek innego kodu w obiekcie. Konstruktor New
może służyć do otwierania plików, nawiązywania połączenia z bazami danych, inicjowania zmiennych i dbania o wszelkie inne zadania, które należy wykonać, zanim będzie można użyć obiektu.
Po utworzeniu Sub New
wystąpienia klasy pochodnej, najpierw wykonywany jest konstruktor klasy bazowej, a następnie wykonywane są konstruktory w klasach pochodnych. Dzieje się tak, ponieważ pierwszy wiersz kodu w konstruktorze Sub New
używa składni MyBase.New()
do wywoływania konstruktora klasy bezpośrednio powyżej samej w hierarchii klas.
Sub New
Konstruktor jest następnie wywoływany dla każdej klasy w hierarchii klas, aż do osiągnięcia konstruktora dla klasy bazowej. W tym momencie uruchamiany jest kod w konstruktorze klasy bazowej, po czym wykonywany jest kod w konstruktorach wszystkich klas pochodnych, a na końcu wykonywany jest kod w konstruktorach najbardziej wyspecjalizowanych klas.
Gdy obiekt nie jest już potrzebny, clR wywołuje metodę Finalize dla tego obiektu przed zwolnieniem pamięci. Metoda Finalize jest nazywana destructor
, ponieważ wykonuje czynności porządkowe, takie jak zapisywanie informacji o stanie, zamykanie plików i połączeń z bazami danych oraz inne zadania, które należy wykonać przed zwolnieniem obiektu.
Interfejs IDisposable
Wystąpienia klas często kontrolują zasoby, które nie są zarządzane przez clR, takie jak obsługa systemu Windows i połączenia bazy danych. Te zasoby muszą zostać usunięte w Finalize
metodzie klasy, tak aby były zwalniane, gdy obiekt zostanie zniszczony przez moduł odśmiecenia pamięci. Jednak moduł odśmieceń pamięci niszczy obiekty tylko wtedy, gdy clR wymaga więcej wolnej pamięci. Oznacza to, że zasoby mogą nie być zwalniane jeszcze przez długi czas po tym, jak obiekt przekroczy zakres.
Aby uzupełnić zbiór odpadów, klasy mogą zapewniać mechanizm aktywnego zarządzania zasobami systemowymi, jeśli implementują interfejs IDisposable.
IDisposable ma jedną metodę , Disposektórą klienci powinni wywołać po zakończeniu korzystania z obiektu. Możesz użyć Dispose metody , aby natychmiast zwolnić zasoby i wykonywać zadania, takie jak zamykanie plików i połączeń bazy danych. W przeciwieństwie do Finalize
destruktora, metoda Dispose nie jest wywoływana automatycznie. Klienci klasy muszą jawnie wywoływać Dispose , gdy chcesz natychmiast zwolnić zasoby.
Implementowanie interfejsu IDisposable
Klasa, która implementuje IDisposable interfejs, powinna zawierać następujące sekcje kodu:
Pole do śledzenia, czy obiekt został usunięty:
Protected disposed As Boolean = False
Przeciążenie Dispose zwalniające zasoby klasy. Ta metoda powinna być wywoływana przez metody Dispose i
Finalize
klasy bazowej.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
Implementacja tej funkcji Dispose zawiera tylko następujący kod:
Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub
Zastąpienie
Finalize
metody zawierającej tylko następujący kod:Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub
Wyprowadzanie z klasy implementującej IDisposable
Klasa, która pochodzi z klasy bazowej, która implementuje IDisposable interfejs, nie musi zastępować żadnej z metod podstawowych, chyba że używa dodatkowych zasobów, które należy usunąć. W takiej sytuacji klasa pochodna powinna zastąpić metodę klasy bazowej, aby usunąć zasoby klasy Dispose(disposing)
pochodnej. To zastąpienie musi wywołać metodę klasy bazowej Dispose(disposing)
.
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
Klasa pochodna nie powinna zastępować metod Dispose i Finalize
klasy bazowej. Gdy metody te są wywoływane z wystąpienia klasy pochodnej, implementacja tych metod w klasie bazowej wywołuje przesłoniętą metodę Dispose(disposing)
klasy pochodnej.
Zbieranie śmieci i finalizowanie destruktora
Program .NET Framework używa systemu zbierania śmieci śledzącego odwołania do okresowego zwalniania nieużywanych zasobów. W programie Visual Basic 6.0 i starszych wersjach użyto innego systemu o nazwie zliczanie odwołań do zarządzania zasobami . Chociaż oba systemy wykonują tę samą funkcję automatycznie, istnieje kilka ważnych różnic.
ClR okresowo niszczy obiekty, gdy system określa, że takie obiekty nie są już potrzebne. Obiekty są zwalniane szybciej, gdy zasoby systemowe są na wyczerpaniu, a rzadziej w innym przypadku. Opóźnienie między utratą zakresu przez obiekt a jego zwolnieniem przez CLR oznacza, że w przeciwieństwie do obiektów w języku Visual Basic 6.0 i wcześniejszych wersjach, nie można dokładnie określić, kiedy obiekt zostanie zniszczony. W takiej sytuacji mówi się, że obiekty mają niedeterministyczny okres istnienia. W większości przypadków niedeterministyczny okres istnienia nie zmienia sposobu pisania aplikacji, o ile pamiętasz, że Finalize
destruktor może nie być wykonywany natychmiast, gdy obiekt opuści zakres.
Kolejna różnica między systemami odzyskiwania pamięci obejmuje użycie elementu Nothing
. Aby skorzystać z zliczania odwołań w Visual Basic 6.0 i starszych wersjach, programiści czasami przypisywali Nothing
do zmiennych obiektów w celu zwolnienia odwołań, które przechowywały te zmienne. Jeśli zmienna przechowywała ostatnie odwołanie do obiektu, zasoby obiektu zostały natychmiast zwolnione. W późniejszych wersjach języka Visual Basic, mimo że mogą występować przypadki, w których ta procedura jest nadal cenna, jej wykonanie nigdy nie powoduje natychmiastowego zwolnienia zasobów przez obiekt, na który się powołano. Aby natychmiast zwolnić zasoby, użyj metody obiektu Dispose , jeśli jest dostępna. Jedyną sytuacją, w której należy ustawić zmienną na Nothing
, jest ta, gdy jej okres istnienia jest długi w stosunku do czasu, którego potrzeba, aby moduł zarządzania pamięcią wykrył osierocone obiekty.