Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Instance třídy, objektu, je vytvořena pomocí klíčového New slova. Úlohy inicializace se často musí provádět u nových objektů, než se použijí. Mezi běžné úlohy inicializace patří otevírání souborů, připojování k databázím a čtení hodnot klíčů registru. Visual Basic řídí inicializaci nových objektů pomocí procedur nazývaných konstruktory (speciální metody, které umožňují kontrolu nad inicializací).
Jakmile objekt opustí obor, uvolní ho modul CLR (Common Language Runtime). Visual Basic řídí uvolnění systémových prostředků pomocí procedur nazývaných destruktory. Konstruktory a destruktory společně podporují vytváření robustních a předvídatelných knihoven tříd.
Použití konstruktorů a destruktorů
Konstruktory a destruktory řídí vytváření a zničení objektů. Postupy Sub New a Sub Finalize v jazyce Visual Basic inicializují a ničí objekty; nahrazují metody Class_Initialize a Class_Terminate používané ve verzi Visual Basic 6.0 a dřívějších verzích.
Sub New
Konstruktor Sub New lze spustit pouze jednou při vytvoření třídy. Nelze ji volat explicitně jinam než v prvním řádku kódu jiného konstruktoru ze stejné třídy nebo z odvozené třídy. Kromě toho kód v Sub New metodě vždy běží před jakýmkoli jiným kódem ve třídě. Visual Basic implicitně vytvoří Sub New konstruktor za běhu, pokud explicitně nedefinujete proceduru Sub New pro třídu.
Chcete-li vytvořit konstruktor pro třídu, vytvořte proceduru pojmenovanou Sub New kdekoli v definici třídy. Pokud chcete vytvořit parametrizovaný konstruktor, zadejte názvy a datové typy argumentů Sub New stejně, jako byste zadali argumenty pro jakýkoli jiný postup, jako v následujícím kódu:
Sub New(ByVal s As String)
Konstruktory jsou často přetížené, stejně jako v následujícím kódu:
Sub New(ByVal s As String, i As Integer)
Když definujete třídu odvozenou z jiné třídy, první řádek konstruktoru musí být volání konstruktoru základní třídy, pokud základní třída nemá přístupný konstruktor, který nepřijímá žádné parametry. Volání na základní třídu, která obsahuje konstruktor uvedený výše, by například bylo MyBase.New(s).
MyBase.New Jinak je volitelný a modul runtime jazyka Visual Basic ho implicitně volá.
Po napsání kódu pro volání konstruktoru nadřazeného objektu můžete do Sub New procedury přidat jakýkoli další inicializační kód.
Sub New může přijímat argumenty při zavolání jako parametrizovaný konstruktor. Tyto parametry jsou předány z procedury volání konstruktoru, Dim AnObject As New ThisClass(X)například .
Dílčí dokončení
Před uvolněním objektů CLR automaticky volá metodu Finalize pro objekty, které definují proceduru Sub Finalize . Metoda Finalize může obsahovat kód, který se musí provést těsně před zničením objektu, například kód pro zavření souborů a uložení informací o stavu. Existuje mírné snížení výkonu při provádění Sub Finalize, takže byste měli definovat metodu Sub Finalize pouze v případě, že potřebujete uvolnit objekty explicitně.
Poznámka:
Správce paměti v modulu CLR neprovádí (a nemůže provádět) likvidaci nespravovaných objektů, objektů, které operační systém spouští přímo mimo prostředí CLR. Důvodem je to, že různé nespravované objekty musí být likvidovány různými způsoby. Tato informace není přímo přidružena k nespravovanému objektu; musí být nalezen v dokumentaci pro objekt. Třída, která používá nespravované objekty, je musí ve své Finalize metodě uvolnit.
Destruktor Finalize je chráněná metoda, kterou lze volat pouze z třídy, do které patří, nebo z odvozených tříd. Systém volá Finalize automaticky při zničení objektu, takže byste neměli explicitně volat Finalize mimo implementaci Finalize odvozené třídy.
Na rozdíl od Class_Terminate, který se spustí, jakmile je objekt nastaven na null, je obvykle zpoždění mezi okamžikem, kdy objekt ztratí svou platnost, a chvílí, kdy Visual Basic zavolá Finalize destruktor. Visual Basic .NET umožňuje druhý druh destruktoru, IDisposable.Disposekterý lze explicitně volat kdykoli k okamžitému uvolnění prostředků.
Poznámka:
Finalize Destruktor by neměl vyvolat výjimky, protože aplikace je nemůže zpracovat a může způsobit ukončení aplikace.
Jak fungují nové a finalizované metody v hierarchii tříd
Při každém vytvoření instance třídy se modul CLR (Common Language Runtime) pokusí spustit proceduru s názvem New, pokud v tomto objektu existuje.
New je typ procedury, která se nazývá constructor , která se používá k inicializaci nových objektů před spuštěním jakéhokoli jiného kódu v objektu. Konstruktor New lze použít k otevření souborů, připojení k databázím, inicializaci proměnných a o všechny další úlohy, které je potřeba provést před použití objektu.
Při vytvoření instance odvozené třídy se Sub New konstruktor základní třídy spustí nejprve, následovaný konstruktory v odvozených třídách. K tomu dochází, protože první řádek kódu v konstruktoru Sub New používá syntaxi MyBase.New()k volání konstruktoru třídy bezprostředně nad sebou v hierarchii tříd. Konstruktor Sub New se pak volá pro každou třídu v hierarchii tříd, dokud se nedosáhne konstruktoru základní třídy. V tomto okamžiku se kód v konstruktoru pro základní třídu spustí, následovaný kódem v každém konstruktoru ve všech odvozených třídách a kód ve většině odvozených tříd se spustí jako poslední.
Pokud objekt již není potřeba, CLR volá metodu Finalize pro tento objekt před uvolněním paměti. Metoda Finalize se nazývá, destructor protože provádí úlohy čištění, jako je ukládání informací o stavu, zavření souborů a připojení k databázím a další úlohy, které je třeba provést před uvolněním objektu.
Rozhraní IDisposable
Instance tříd často řídí prostředky, které nespravuje CLR, jako jsou obslužné rutiny Windows a připojení k databázi. Tyto prostředky musí být zlikvidovány v Finalize metodě třídy, aby byly správně uvolněny při zničení objektu správcem paměti. Správce paměti však odstraní objekty pouze v případě, že CLR vyžaduje více volné paměti. To znamená, že prostředky nemusí být uvolněny dlouho poté, co objekt vyjde z rozsahu.
Aby třídy mohly doplnit automatizované uvolňování paměti, mohou poskytovat mechanismus pro aktivní správu systémových prostředků, pokud implementují rozhraní IDisposable.
IDisposable má jednu metodu, Disposekterou by klienti měli volat, když dokončí použití objektu. Tuto metodu Dispose můžete použít k okamžitému uvolnění prostředků a provádění úloh, jako jsou zavření souborů a připojení k databázi. Na rozdíl od Finalize destruktoru není Dispose metoda volána automaticky. Klienti třídy musí explicitně volat Dispose , pokud chcete okamžitě uvolnit prostředky.
Implementace IDisposable
Třída, která implementuje IDisposable rozhraní, by měla obsahovat tyto části kódu:
Pole pro sledování toho, jestli byl objekt odstraněn:
Protected disposed As Boolean = FalsePřetížení Dispose, které uvolňuje prostředky třídy. Tato metoda by měla být volána metodami Dispose
Finalizezákladní třídy: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 SubImplementace Dispose , která obsahuje pouze následující kód:
Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End SubPřepsání metody
Finalize, které obsahuje pouze následující kód:Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub
Odvození z třídy, která implementuje IDisposable
Třída odvozená od základní třídy, která implementuje IDisposable rozhraní, nemusí přepsat žádnou ze základních metod, pokud nepoužívá další prostředky, které je potřeba odstranit. V takovém případě by odvozená třída měla přepsat metodu základní třídy Dispose(disposing) aby uvolnila prostředky odvozené třídy. Toto přepsání musí volat metodu Dispose(disposing) základní třídy.
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
Odvozená třída by neměla překrývat metody Dispose a Finalize základní třídy. Pokud jsou tyto metody volány z instance odvozené třídy, implementace základní třídy těchto metod volá přepsané metody Dispose(disposing) odvozené třídy.
Uvolňování paměti a finalizační destruktor
Rozhraní .NET Framework používá systém garbage collection na základě sledování odkazů k pravidelnému uvolňování nevyužívaných prostředků. Visual Basic 6.0 a starší verze používaly jiný systém označovaný jako počítání odkazů ke správě prostředků. I když oba systémy provádějí stejnou funkci automaticky, existuje několik důležitých rozdílů.
CLR pravidelně zničí objekty, když systém určí, že tyto objekty už nejsou potřeba. Objekty se uvolňují rychleji, když jsou systémové prostředky omezené, a méně často za jiných okolností. Zpoždění mezi tím, kdy objekt ztratí obor a kdy CLR uvolní, znamená to, že na rozdíl od objektů v jazyce Visual Basic 6.0 a starších verzí nelze přesně určit, kdy bude objekt zničen. V takové situaci se říká, že objekty mají ne deterministické životnosti. Ve většině případů nedeterministické životnosti nemění způsob psaní aplikací, pokud si pamatujete, že Finalize destruktor nemusí být okamžitě spuštěn při ztrátě oboru objektu.
Dalším rozdílem mezi systémy uvolňování paměti je použití Nothing. Aby programátoři mohli využít počítání odkazů v jazyce Visual Basic 6.0 a starších verzích, někdy přiřadili Nothing objektovým proměnným, aby uvolnili odkazy, které tyto proměnné držely. Pokud proměnná držela poslední odkaz na objekt, prostředky objektu byly uvolněny okamžitě. V novějších verzích jazyka Visual Basic mohou existovat případy, kdy je tento postup stále cenný, ale jeho provedení nikdy nezpůsobí okamžité uvolnění prostředků odkazovaným objektem. Pokud chcete uvolnit prostředky okamžitě, použijte metodu objektu Dispose , pokud je k dispozici. Jediný čas, kdy byste měli nastavit proměnnou Nothing, je, když její životnost je dlouhá ve srovnání s dobou, při které uvolňování paměti detekuje osamocené objekty.