Objektum élettartama: Objektumok létrehozása és megsemmisítése (Visual Basic)
Az osztály egy példánya, egy objektum a kulcsszó használatával New
jön létre. Az inicializálási feladatokat gyakran el kell végezni az új objektumokon a használat előtt. A gyakori inicializálási feladatok közé tartozik a fájlok megnyitása, az adatbázisokhoz való csatlakozás és a beállításkulcsok értékeinek olvasása. A Visual Basic konstruktoroknak nevezett eljárásokkal szabályozza az új objektumok inicializálását (speciális módszerek, amelyek lehetővé teszik az inicializálás vezérlését).
Miután egy objektum elhagyja a hatókört, a rendszer kiadja a közös nyelvi futtatókörnyezet (CLR) által. A Visual Basic a rendszererőforrások kiadását destruktoroknak nevezett eljárásokkal szabályozza. A konstruktorok és a destruktorok együttesen támogatják a robusztus és kiszámítható osztálykódtárak létrehozását.
Konstruktorok és destruktorok használata
A konstruktorok és a destruktorok szabályozzák az objektumok létrehozását és megsemmisítését. Sub Finalize
A Sub New
Visual Basicben található eljárások inicializálják és megsemmisítik az objektumokat; lecserélik a Class_Initialize
Class_Terminate
Visual Basic 6.0-s és korábbi verzióiban használt módszereket és metódusokat.
Új al
A Sub New
konstruktor csak egyszer futtatható egy osztály létrehozásakor. Nem hívható meg explicit módon máshol, mint egy másik konstruktor kódjának első sorában ugyanabból az osztályból vagy származtatott osztályból. Ezenkívül a Sub New
metódus kódja mindig az osztály bármely más kódja előtt fut. A Visual Basic implicit módon létrehoz egy konstruktort Sub New
futásidőben, ha nem határoz meg explicit módon eljárást Sub New
egy osztályhoz.
Egy osztály konstruktorának létrehozásához hozzon létre egy, az osztálydefinícióban bárhol elnevezett Sub New
eljárást. Paraméteres konstruktor létrehozásához adja meg az argumentumok nevét és adattípusait Sub New
úgy, ahogyan bármely más eljárás argumentumait is megadhatja, ahogyan az alábbi kódban is:
Sub New(ByVal s As String)
A konstruktorok gyakran túlterheltek, mint az alábbi kódban:
Sub New(ByVal s As String, i As Integer)
Ha egy másik osztályból származtatott osztályt határoz meg, a konstruktor első sora az alaposztály konstruktorának hívása lehet, kivéve, ha az alaposztály olyan akadálymentes konstruktorsal rendelkezik, amely nem használ paramétereket. A fenti konstruktort tartalmazó alaposztály hívása például a következő: MyBase.New(s)
. MyBase.New
Ellenkező esetben nem kötelező, és a Visual Basic futtatókörnyezet implicit módon hívja meg.
Miután megírta a szülőobjektum konstruktorának meghívására vonatkozó kódot, bármilyen további inicializálási kódot hozzáadhat az Sub New
eljáráshoz. Sub New
paraméteres konstruktorként meghívva argumentumokat fogadhat el. Ezeket a paramétereket a konstruktort meghívó eljárás adja át, például Dim AnObject As New ThisClass(X)
.
Rész véglegesítése
Az objektumok felszabadítása előtt a CLR automatikusan meghívja az Finalize
eljárást meghatározó objektumok metódusát Sub Finalize
. A Finalize
metódus tartalmazhat olyan kódot, amelyet egy objektum megsemmisítése előtt végre kell hajtani, például a fájlok bezárására és az állapotadatok mentésére szolgáló kódot. A végrehajtás Sub Finalize
enyhe teljesítménybeli büntetést jelent, ezért csak akkor kell meghatároznia egy metódust Sub Finalize
, ha explicit módon kell felszabadítania az objektumokat.
Feljegyzés
A CLR-ben a szemétgyűjtő nem (és nem is) semmisít meg nem felügyelt objektumokat, objektumokat, amelyeket az operációs rendszer közvetlenül hajt végre a CLR-környezeten kívül. Ennek az az oka, hogy a különböző nem felügyelt objektumokat különböző módokon kell megsemmisíteni. Ez az információ nincs közvetlenül társítva a nem felügyelt objektummal; az objektum dokumentációjában kell lennie. A nem felügyelt objektumokat használó osztálynak a metódusában Finalize
kell megsemmisítenie őket.
A Finalize
destruktor egy védett metódus, amely csak a hozzá tartozó osztályból vagy származtatott osztályokból hívható meg. A rendszer automatikusan hív Finalize
, amikor egy objektum megsemmisül, ezért nem szabad explicit módon meghívni Finalize
egy származtatott osztály implementációján Finalize
kívülről.
Ellentétben Class_Terminate
azokkal a műveletekkel, amelyek akkor hajtanak végre, amikor egy objektum nincs beállítva semmire, általában késés van a hatókör elvesztése és a Visual Basic meghívja a Finalize
destruktort. A Visual Basic .NET lehetővé teszi a második típusú destruktor használatát, IDisposable.Disposeamely bármikor explicit módon hívható meg az erőforrások azonnali felszabadításához.
Feljegyzés
A Finalize
destruktorok nem adhatnak kivételeket, mert azokat az alkalmazás nem tudja kezelni, és az alkalmazás leállását okozhatja.
Az új és véglegesítési metódusok működése osztályhierarchiában
Amikor létrejön egy osztály egy példánya, a közös nyelvi futtatókörnyezet (CLR) megpróbál végrehajtani egy nevű New
eljárást, ha az az objektumban létezik. New
az új objektumok inicializálására szolgáló eljárástípus constructor
, amely egy objektum bármely más kódjának végrehajtása előtt inicializálódik. A New
konstruktorok fájlok megnyitására, adatbázisokhoz való csatlakozásra, változók inicializálására és az objektumok használatához szükséges egyéb feladatok elvégzésére használhatók.
Származtatott osztály létrehozásakor az Sub New
alaposztály konstruktora hajtja végre először, majd a származtatott osztályok konstruktorai. Ez azért fordul elő, mert a konstruktor első kódsora Sub New
a szintaxis MyBase.New()
használatával hívja meg az osztály konstruktorát közvetlenül felette az osztályhierarchiában. Ezután Sub New
a rendszer meghívja a konstruktort az osztályhierarchia minden osztályához, amíg el nem éri az alaposztály konstruktorát. Ezen a ponton az alaposztály konstruktorában lévő kód fut, amelyet az egyes konstruktorokban lévő kód követ az összes származtatott osztályban, és a legtöbb származtatott osztály kódját végre kell hajtani utoljára.
Ha már nincs szükség egy objektumra, a CLR meghívja az Finalize objektum metódusát, mielőtt felszabadítja a memóriáját. A Finalize metódus elnevezése destructor
azért van, mert olyan karbantartási feladatokat hajt végre, mint például az állapotadatok mentése, az adatbázisokhoz kapcsolódó fájlok és kapcsolatok bezárása, valamint az objektum felszabadítása előtt végrehajtandó egyéb feladatok.
IDisposable Interface
Az osztálypéldányok gyakran szabályozzák a CLR által nem felügyelt erőforrásokat, például a Windows-leírókat és az adatbázis-kapcsolatokat. Ezeket az erőforrásokat az Finalize
osztály metódusában kell megsemmisíteni, hogy azok felszabadulnak, amikor a szemétgyűjtő megsemmisíti az objektumot. A szemétgyűjtő azonban csak akkor pusztítja el az objektumokat, ha a CLR több szabad memóriát igényel. Ez azt jelenti, hogy az erőforrások csak akkor szabadulnak fel, ha az objektum ki nem lép a hatókörből.
A szemétgyűjtés kiegészítéséhez az osztályok mechanizmust biztosíthatnak a rendszererőforrások aktív kezeléséhez, ha implementálják a IDisposable felületet. IDisposable egy metódussal rendelkezik, Disposeamelyet az ügyfeleknek meg kell hívniuk, amikor befejezik az objektum használatát. Ezzel a módszerrel azonnal felszabadíthatja az Dispose erőforrásokat, és olyan feladatokat hajthat végre, mint például a fájlok és az adatbázis-kapcsolatok bezárása. A Finalize
destruktortól eltérően a Dispose metódus nem lesz automatikusan meghívva. Az osztály ügyfeleinek kifejezetten fel kell hívniuk Dispose az erőforrások azonnali felszabadítását.
Az IDisposable implementálása
Az interfészt megvalósító osztálynak a IDisposable következő kódszakaszokat kell tartalmaznia:
Egy mező, amely nyomon követi, hogy az objektum el lett-e helyezve:
Protected disposed As Boolean = False
Az osztály erőforrásait felszabadító túlterhelés Dispose . Ezt a metódust az alaposztály és
Finalize
a Dispose metódusok hívhatják meg: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
Ennek implementációja Dispose csak a következő kódot tartalmazza:
Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub
A metódus felülbírálása
Finalize
, amely csak a következő kódot tartalmazza:Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub
Az IDisposable-t implementáló osztályból származik
Az interfészt megvalósító alaposztályból származó osztálynak nem kell felülbírálnia az alapmódszereket IDisposable , kivéve, ha további, elidegenítendő erőforrásokat használ. Ebben az esetben a származtatott osztálynak felül kell bírálnia az alaposztály metódusát Dispose(disposing)
a származtatott osztály erőforrásainak ártalmatlanítására. Ennek a felülbírálásnak meg kell hívnia az alaposztály metódusát 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
A származtatott osztály nem bírálhatja Dispose felül az alaposztály és Finalize
a metódusok használatát. Ha ezeket a metódusokat a származtatott osztály egy példányából hívják meg, az alaposztály implementációja meghívja a származtatott osztály metódus felülbírálását Dispose(disposing)
.
Szemétgyűjtés és a véglegesítési destruktor
A .NET-keretrendszer a referencia-nyomkövetési szemétgyűjtési rendszert használja a nem használt erőforrások rendszeres felszabadítására. A Visual Basic 6.0-s és korábbi verziói egy másik rendszert, az úgynevezett referenciaszámlálást használtak az erőforrások kezeléséhez. Bár mindkét rendszer automatikusan ugyanazt a funkciót végzi el, van néhány fontos különbség.
A CLR rendszeres időközönként megsemmisíti az objektumokat, amikor a rendszer megállapítja, hogy ezekre az objektumokra már nincs szükség. Az objektumok gyorsabban szabadulnak fel, ha a rendszererőforrások rendelkezésre állnak, és ritkábban másként. Az objektum hatókörének elvesztése és a CLR kiadásának késleltetése azt jelenti, hogy a Visual Basic 6.0-s és korábbi verzióiban lévő objektumokkal ellentétben nem lehet pontosan meghatározni, hogy mikor lesz megsemmisítve az objektum. Ilyen helyzetben a tárgyaknak nem determinisztikus élettartamuk van. A legtöbb esetben a nem determinisztikus élettartam nem változtatja meg az alkalmazások írásának módját, feltéve, hogy Finalize
a destruktor nem feltétlenül fut azonnal, ha egy objektum elveszíti a hatókörét.
A szemétgyűjtési rendszerek közötti másik különbség a Nothing
. A Visual Basic 6.0-s és korábbi verzióiban a hivatkozásszámlálás előnyeinek kihasználásához a programozók néha objektumváltozókhoz vannak rendelve Nothing
, hogy felszabadíthassák a tárolt változókra mutató hivatkozásokat. Ha a változó az objektumra mutató utolsó hivatkozást tartotta, az objektum erőforrásai azonnal felszabadultak. A Visual Basic későbbi verzióiban, bár lehetnek olyan esetek, amikor ez az eljárás még mindig értékes, a művelet végrehajtása soha nem eredményezi, hogy a hivatkozott objektum azonnal felszabadítsa az erőforrásait. Az erőforrások azonnali felszabadításához használja az objektum metódusát Dispose , ha van ilyen. A változók Nothing
csak akkor állíthatók be, ha élettartamuk hosszú ahhoz képest, hogy a szemétgyűjtő mennyi időt vesz igénybe az árva objektumok észleléséhez.