L'istruzione using in C#
Nella lezione precedente abbiamo parlato della clausola finally
e di come possiamo usarla per garantire che le risorse vengano sempre rilasciate, anche se si verifica un'eccezione o viene eseguita un'istruzione return
all'interno del blocco try
.
Esiste, tuttavia, un modo più semplice e conveniente per gestire le risorse in C# utilizzando l'istruzione using
.
Tuttavia, l'istruzione using
non pulisce qualsiasi tipo di risorsa, ma solo quelle che implementano l'interfaccia IDisposable
. In questa lezione, esploreremo l'interfaccia IDisposable
, il suo scopo e come utilizzare l'istruzione using
per gestire le risorse in modo efficace.
- L'istruzione
using
in C# è utilizzata per gestire le risorse che implementano l'interfacciaIDisposable
. - L'interfaccia
IDisposable
fornisce un metodo chiamatoDispose()
che viene utilizzato per rilasciare le risorse allocate da una classe. - L'istruzione
using
semplifica la gestione delle risorse, garantendo che le risorse vengano rilasciate automaticamente al termine del bloccousing
. - È consigliabile utilizzare l'istruzione
using
con tutte le classi che implementano l'interfacciaIDisposable
per garantire il rilascio corretto delle risorse.
L'Interfaccia IDisposable
L'uso principale dell'interfaccia IDisposable
è rilasciare risorse.
In .NET tali risorse sono handle di finestre, file, stream e altri oggetti.
Non entreremo nei dettagli su come implementare IDisposable
poiché dobbiamo andare molto più in profondità e spiegare come funziona il garbage collector, come usare i distruttori, le risorse non gestite e così via.
Il metodo importante nell'interfaccia IDisposable
è Dispose()
. La cosa principale che dobbiamo sapere sul metodo è che rilascia le risorse della classe che lo implementa. Nei casi in cui le risorse sono stream, reader o file, il rilascio delle risorse può essere fatto usando il metodo Dispose()
dall'interfaccia IDisposable
, che chiama il loro metodo Close()
. Questo metodo li chiude e rilascia le loro risorse. Quindi per chiudere uno stream possiamo fare quanto segue:
StreamReader lettore = new StreamReader(nomeFile);
try
{
// Usa il lettore qui
}
finally
{
if (lettore != null)
{
lettore.Dispose();
}
}
L'istruzione using
L'esempio precedente può essere scritto in forma più breve con l'aiuto della parola chiave using
in C#, come mostrato nell'esempio seguente:
using (StreamReader lettore = new StreamReader(nomeFile))
{
// Usa il lettore qui
}
La forma semplificata del "pattern dispose" sopra riportata è semplice da scrivere, semplice da usare e semplice da leggere. Inoltre garantisce il rilascio corretto delle risorse allocate specificate nelle parentesi dell'istruzione using
.
Non è necessario avere try
-finally
o chiamare esplicitamente alcun metodo per rilasciare le risorse. Il compilatore si occupa di inserire automaticamente il blocco try
-finally
e le risorse utilizzate vengono rilasciate chiamando il metodo Dispose()
dopo aver lasciato il blocco using
.
Più avanti nelle lezioni successive utilizzeremo estensivamente l'istruzione using
per leggere e scrivere correttamente i file di testo.
Istruzioni using
nidificate
Le istruzioni using
possono essere nidificate una dentro l'altra:
using (TipoRisorsa r1 = ...)
using (TipoRisorsa r2 = ...)
/* ... */
using (TipoRisorsa rN = ...)
{
istruzioni;
}
In alternativa, possiamo dichiarare più risorse in un'unica istruzione using
:
using (TipoRisorsa r1 = ..., r2 = ..., ..., rN = ...)
{
istruzioni;
}
È importante menzionare che l'istruzione using
non è correlata alla gestione delle eccezioni. Il suo unico scopo è rilasciare le risorse indipendentemente dal fatto che vengano lanciate eccezioni o meno.
Non gestisce le eccezioni.
Pertanto, possiamo usare comunque un blocco try
-catch
all'interno di un blocco using
per gestire le eccezioni, se necessario. Ad esempio:
using (StreamReader lettore = new StreamReader(nomeFile))
{
try
{
// Usa il lettore qui
}
catch (Exception ex)
{
// Gestisci l'eccezione qui
}
}
Come si può osservare, l'istruzione using
semplifica notevolmente la gestione delle risorse in C#, rendendo il codice più pulito e leggibile. Non abbiamo avuto il bisogno di aggiungere una clausola finally
per rilasciare le risorse, poiché l'istruzione using
si occupa automaticamente di questo.
Quando Usare l'Istruzione using
Esiste una regola semplice su quando usare using con le classi .NET:
Regola per l'uso di using
Utilizzare l'istruzione using con tutte le classi che implementano l'interfaccia IDisposable
.
Cercare IDisposable
in MSDN.
Quando una classe implementa l'interfaccia IDisposable
questo significa che il creatore di questa classe si aspetta che possa essere utilizzata con l'istruzione using
e la classe contiene qualche risorsa costosa che non dovrebbe essere lasciata non rilasciata.
Implementare IDisposable
significa anche che dovrebbe essere rilasciata immediatamente dopo aver finito di usare la classe e il modo più semplice per farlo in C# è con l'istruzione using
.