Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Un'istanza di una classe, un oggetto , viene creata usando la New
parola chiave . Le attività di inizializzazione devono spesso essere eseguite su nuovi oggetti prima di essere usate. Le attività di inizializzazione comuni includono l'apertura di file, la connessione ai database e la lettura dei valori delle chiavi del Registro di sistema. Visual Basic controlla l'inizializzazione di nuovi oggetti usando procedure denominate costruttori (metodi speciali che consentono il controllo sull'inizializzazione).
Dopo che un oggetto lascia l'ambito, viene rilasciato dal runtime del linguaggio comune (CLR). Visual Basic controlla il rilascio delle risorse di sistema usando procedure denominate distruttori. Insieme, costruttori e distruttori supportano la creazione di librerie di classi affidabili e prevedibili.
Utilizzo di costruttori e distruttori
Costruttori e distruttori controllano la creazione e la distruzione di oggetti. Le Sub New
procedure e Sub Finalize
in Visual Basic inizializzano ed eliminano gli oggetti e sostituiscono i Class_Initialize
metodi e Class_Terminate
usati in Visual Basic 6.0 e versioni precedenti.
Sub New
Il Sub New
costruttore può essere eseguito una sola volta quando viene creata una classe. Non può essere chiamato in modo esplicito in qualsiasi punto diverso dalla prima riga di codice di un altro costruttore dalla stessa classe o da una classe derivata. Inoltre, il codice nel Sub New
metodo viene sempre eseguito prima di qualsiasi altro codice in una classe. Visual Basic crea in modo implicito un Sub New
costruttore in fase di esecuzione se non si definisce in modo esplicito una Sub New
routine per una classe.
Per creare un costruttore per una classe, creare una routine denominata Sub New
in qualsiasi punto della definizione della classe. Per creare un costruttore con parametri, specificare i nomi e i tipi di dati degli argomenti in Sub New
modo da specificare gli argomenti per qualsiasi altra routine, come nel codice seguente:
Sub New(ByVal s As String)
I costruttori vengono spesso sovraccaricati, come nel codice seguente:
Sub New(ByVal s As String, i As Integer)
Quando si definisce una classe derivata da un'altra classe, la prima riga di un costruttore deve essere una chiamata al costruttore della classe base, a meno che la classe base non abbia un costruttore accessibile che non accetta parametri. Una chiamata alla classe base che contiene il costruttore precedente, ad esempio, sarebbe MyBase.New(s)
. In caso contrario, MyBase.New
è facoltativo e il runtime di Visual Basic lo chiama in modo implicito.
Dopo aver scritto il codice per chiamare il costruttore dell'oggetto padre, è possibile aggiungere qualsiasi codice di inizializzazione aggiuntivo alla Sub New
routine.
Sub New
può accettare argomenti quando viene chiamato come costruttore con parametri. Questi parametri vengono passati dalla routine che chiama il costruttore, Dim AnObject As New ThisClass(X)
ad esempio .
Sub Finalize
Prima di rilasciare gli oggetti, CLR chiama automaticamente il Finalize
metodo per gli oggetti che definiscono una Sub Finalize
routine. Il Finalize
metodo può contenere codice che deve essere eseguito subito prima che un oggetto venga eliminato definitivamente, ad esempio il codice per la chiusura dei file e il salvataggio delle informazioni sullo stato. Si verifica una lieve riduzione delle prestazioni nell'esecuzione di Sub Finalize
, pertanto sì dovrebbe definire un metodo Sub Finalize
solo quando bisogna rilasciare gli oggetti in modo esplicito.
Annotazioni
Il Garbage Collector in CLR non (e non può) eliminare oggetti non gestiti, oggetti eseguiti direttamente dal sistema operativo, all'esterno dell'ambiente CLR. Ciò è dovuto al fatto che diversi oggetti non gestiti devono essere eliminati in modi diversi. Tali informazioni non sono direttamente associate all'oggetto non gestito; deve essere trovato nella documentazione per l'oggetto . Una classe che usa oggetti non gestiti deve eliminarli nel relativo Finalize
metodo.
Il Finalize
distruttore è un metodo protetto che può essere chiamato solo dalla classe a cui appartiene o da classi derivate. Il sistema chiama Finalize
automaticamente quando un oggetto viene eliminato definitivamente, pertanto non è consigliabile chiamare Finalize
in modo esplicito dall'esterno dell'implementazione di Finalize
una classe derivata.
A differenza di Class_Terminate
, che viene eseguito non appena un oggetto è impostato su nulla, in genere si verifica un ritardo tra quando un oggetto perde l'ambito e quando Visual Basic chiama il Finalize
distruttore. Visual Basic .NET consente un secondo tipo di distruttore, IDisposable.Dispose, che può essere chiamato in modo esplicito in qualsiasi momento per rilasciare immediatamente le risorse.
Annotazioni
Un Finalize
distruttore non deve generare eccezioni, perché non può essere gestito dall'applicazione e può causare l'interruzione dell'applicazione.
Funzionamento dei Metodi New e Finalize in una Gerarchia di Classi
Ogni volta che viene creata un'istanza di una classe, Common Language Runtime (CLR) tenta di eseguire una routine denominata New
, se presente in tale oggetto.
New
è un tipo di routine denominato che constructor
viene utilizzato per inizializzare nuovi oggetti prima dell'esecuzione di qualsiasi altro codice in un oggetto . Un New
costruttore può essere usato per aprire i file, connettersi ai database, inizializzare le variabili e occuparsi di qualsiasi altra attività che deve essere eseguita prima di poter usare un oggetto.
Quando viene creata un'istanza di una classe derivata, il Sub New
costruttore della classe di base viene eseguito per primo, seguito dai costruttori nelle classi derivate. Ciò si verifica perché la prima riga di codice in un Sub New
costruttore usa la sintassi MyBase.New()
per chiamare il costruttore della classe immediatamente sopra di se stessa nella gerarchia di classi. Il Sub New
costruttore viene quindi chiamato per ogni classe nella gerarchia di classi finché non viene raggiunto il costruttore per la classe di base. A questo punto, il codice nel costruttore per la classe base viene eseguito, seguito dal codice in ogni costruttore in tutte le classi derivate e il codice nelle classi più derivate viene eseguito per ultimo.
Quando un oggetto non è più necessario, CLR chiama il Finalize metodo per tale oggetto prima di liberarne la memoria. Il Finalize metodo viene chiamato destructor
perché esegue attività di pulizia, come il salvataggio di informazioni sullo stato, la chiusura di file e connessioni ai database, e altre operazioni che devono essere effettuate prima di rilasciare l'oggetto.
Interfaccia IDisposable
Le istanze di classe spesso controllano le risorse non gestite da CLR, ad esempio handle di Windows e connessioni di database. Queste risorse devono essere eliminate nel Finalize
metodo della classe, in modo che vengano rilasciate quando l'oggetto viene eliminato definitivamente dal Garbage Collector. Tuttavia, il garbage collector distrugge gli oggetti solo quando il CLR richiede più memoria libera. Ciò significa che le risorse potrebbero non essere rilasciate fino a quando l'oggetto non esce dall'ambito.
Per integrare Garbage Collection, le classi possono fornire un meccanismo per gestire attivamente le risorse di sistema se implementano l'interfaccia IDisposable .
IDisposable dispone di un metodo, Dispose, che i client devono chiamare al termine dell'uso di un oggetto . È possibile usare il Dispose metodo per rilasciare immediatamente le risorse ed eseguire attività come la chiusura di file e connessioni di database. A differenza del Finalize
distruttore, il Dispose metodo non viene chiamato automaticamente. I client di una classe devono chiamare Dispose in modo esplicito quando si desidera rilasciare immediatamente le risorse.
Implementazione di IDisposable
Una classe che implementa l'interfaccia IDisposable deve includere queste sezioni di codice:
Campo per tenere traccia dell'eliminazione dell'oggetto:
Protected disposed As Boolean = False
Sovraccarico di Dispose che libera le risorse della classe. Questo metodo deve essere chiamato dai metodi Dispose e
Finalize
della classe base.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
Implementazione di Dispose che contiene solo il codice seguente:
Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub
Una sovrascrittura del metodo
Finalize
che contiene solo il seguente codice:Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub
Derivazione da una classe che implementa IDisposable
Una classe che deriva da una classe base che implementa l'interfaccia non deve eseguire l'override IDisposable di uno dei metodi di base, a meno che non usi risorse aggiuntive che devono essere eliminate. In tal caso, la classe derivata deve eseguire l'override del metodo della Dispose(disposing)
classe di base per eliminare le risorse della classe derivata. Questa override deve chiamare il metodo della classe di Dispose(disposing)
base.
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
Una classe derivata non dovrebbe sovrascrivere i metodi Dispose e Finalize
della classe base. Quando questi metodi vengono chiamati su un'istanza della classe derivata, l'implementazione della classe base di tali metodi chiama l'override della classe derivata del metodo Dispose(disposing)
.
Garbage Collection e il distruttore Finalize
.NET Framework usa il sistema di raccolta dei rifiuti a traccia di riferimenti per rilasciare periodicamente le risorse inutilizzate. Visual Basic 6.0 e versioni precedenti usavano un sistema diverso denominato conteggio dei riferimenti per gestire le risorse. Sebbene entrambi i sistemi eseguano automaticamente la stessa funzione, esistono alcune differenze importanti.
CLR elimina periodicamente gli oggetti quando il sistema determina che tali oggetti non sono più necessari. Gli oggetti vengono rilasciati più rapidamente quando le risorse di sistema sono in breve fornitura e meno frequentemente. Il ritardo tra quando un oggetto perde l'ambito e quando CLR rilascia significa che, a differenza degli oggetti in Visual Basic 6.0 e versioni precedenti, non è possibile determinare esattamente quando l'oggetto verrà eliminato definitivamente. In una situazione di questo tipo, si dice che gli oggetti abbiano una durata non deterministica. Nella maggior parte dei casi, la durata non deterministica non cambia la modalità di scrittura delle applicazioni, purché si ricordi che il Finalize
distruttore potrebbe non essere eseguito immediatamente quando un oggetto perde l'ambito.
Un'altra differenza tra i sistemi di raccolta dei rifiuti riguarda l'uso di Nothing
. Per sfruttare i vantaggi del conteggio dei riferimenti in Visual Basic 6.0 e versioni precedenti, i programmatori talvolta assegnavano lo Nothing
alle variabili di oggetto per rilasciare i riferimenti che quelle variabili detenevano. Se la variabile ha mantenuto l'ultimo riferimento all'oggetto, le risorse dell'oggetto vengono rilasciate immediatamente. Nelle versioni successive di Visual Basic, anche se potrebbero verificarsi casi in cui questa procedura è ancora utile, l'esecuzione non comporta mai il rilascio immediato delle risorse da parte dell'oggetto a cui si fa riferimento. Per rilasciare immediatamente le risorse, usare il metodo dell'oggetto Dispose , se disponibile. L'unica volta che è necessario impostare una variabile su Nothing
è quando la durata è lunga rispetto al tempo impiegato dal Garbage Collector per rilevare gli oggetti orfani.