Megosztás a következőn keresztül:


Objektum élettartama: Objektumok létrehozása és megsemmisítése (Visual Basic)

Az osztály egy példánya, egy objektum, a New kulcsszóval 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 közös nyelvi futtatókörnyezet (CLR) felszabadítja azt. 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. A Sub New és Sub Finalize eljárások Visual Basicben inicializálják és megsemmisítik az objektumokat; lecserélik a Class_Initialize és Class_Terminate módszereket, amelyeket a Visual Basic 6.0-s és korábbi verzióiban használtak.

Ú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 azon objektumok metódusát, amelyek egy Finalize eljárást határoznak meg 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. Sub Finalize végrehajtása enyhe teljesítménybeli büntetést von maga után, ezért csak akkor érdemes metódust meghatároznia Sub Finalize, ha explicit módon objektumokat kell felszabadítania.

Megjegyzé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-val, amely akkor hajt végre, amikor egy objektum semmire van beállítva, általában késés van aközött, amikor egy objektum elveszíti a hatókörét, és amikor 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.

Megjegyzé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ű Neweljá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.

Képernyőkép az osztályhierarchia konstruktorairól és örökléséről.

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.

Képernyőkép a Finalize metódus destruktoráról.

IDisposable felület

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 meg kell hívnia a Dispose, ha az erőforrásokat azonnal szeretnék felszabadítani.

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 Dispose és Finalize metódusai hívjá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 IDisposable interfészt megvalósító alaposztályból származó osztálynak nem kell felülbírálnia az alapmódszereket, kivéve, ha további, felszabadítandó 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 írhatja felül az alaposztály Dispose és Finalize metódusait. Amikor 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 Dispose(disposing) metódusának felülírását.

Szemétgyűjtés és a véglegesítési destruktor

A .NET-keretrendszer a referencia-nyomkövető szemétgyűjtési rendszert használja a rendszeresen fel nem használt erőforrások 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, amikor a rendszererőforrások szűkösek, és ritkábban egyébké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. Ne feledje azonban, hogy a Finalize 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 használatát érinti. A Visual Basic 6.0-s és korábbi verzióiban a programozók azért rendeltek Nothing-t az objektumváltozókhoz, hogy felszabadítsák a változók által tartott hivatkozásokat a hivatkozásszámlálás előnyeinek kihasználása érdekében. 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.

Lásd még