Istruzione using - verificare l'uso corretto degli oggetti eliminabili

L'istruzione using garantisce l'uso corretto di un'istanza IDisposable:

var numbers = new List<int>();
using (StreamReader reader = File.OpenText("numbers.txt"))
{
    string line;
    while ((line = reader.ReadLine()) is not null)
    {
        if (int.TryParse(line, out int number))
        {
            numbers.Add(number);
        }
    }
}

Quando il controllo lascia il blocco dell'istruzione using, viene eliminata un'istanza IDisposable acquisita. In particolare, l'istruzione using garantisce che un'istanza eliminabile venga eliminata anche se si verifica un'eccezione all'interno del blocco dell'istruzione using. Nell'esempio precedente un file aperto viene chiuso dopo l'elaborazione di tutte le righe.

Usare l'istruzione await using per usare correttamente un'istanza IAsyncDisposable:

await using (var resource = new AsyncDisposableExample())
{
    // Use the resource
}

Per altre informazioni sull'uso delle istanze IAsyncDisposable, vedere la sezione Uso di un elemento asincrono eliminabile nell'articolo Implementare un metodo DisposeAsync.

È anche possibile usare una dichiarazione using che non richiede parentesi graffe:

static IEnumerable<int> LoadNumbers(string filePath)
{
    using StreamReader reader = File.OpenText(filePath);
    
    var numbers = new List<int>();
    string line;
    while ((line = reader.ReadLine()) is not null)
    {
        if (int.TryParse(line, out int number))
        {
            numbers.Add(number);
        }
    }
    return numbers;
}

Quando viene dichiarata in una dichiarazione using, una variabile locale viene eliminata alla fine dell'ambito in cui è stata dichiarata. Nell'esempio precedente, l'eliminazione avviene alla fine di un metodo.

Una variabile dichiarata dall'istruzione o dalla dichiarazione using è di sola lettura. Non è possibile riassegnarla o passarla come parametro ref o out.

È possibile dichiarare più istanze dello stesso tipo in un'istruzione using, come illustrato nell'esempio seguente:

using (StreamReader numbersFile = File.OpenText("numbers.txt"), wordsFile = File.OpenText("words.txt"))
{
    // Process both files
}

Quando si dichiarano più istanze in un'istruzione using, queste vengono eliminate in ordine inverso rispetto alla dichiarazione.

È anche possibile usare l'istruzione e la dichiarazione using con un'istanza di un tipo ref struct che corrisponde al criterio eliminabile. Ovvero, abbia un metodo di istanza Dispose, sia accessibile, senza parametri e abbia un tipo restituito void.

L'istruzione using può anche avere il formato seguente:

using (expression)
{
    // ...
}

dove expression produce un'istanza eliminabile. L'esempio seguente lo dimostra:

StreamReader reader = File.OpenText(filePath);

using (reader)
{
    // Process file content
}

Avviso

Nell'esempio precedente, dopo che il controllo lascia l'istruzione using, un'istanza eliminabile rimane nell'ambito mentre è già stata eliminata. Se si usa ulteriormente tale istanza, è possibile che si verifichi un'eccezione, ad esempio ObjectDisposedException. Per questo motivo è consigliabile dichiarare una variabile eliminabile all'interno dell'istruzione using o con la dichiarazione using.

Specifiche del linguaggio C#

Per altre informazioni, vedere la sezione Istruzione using delle Specifiche del linguaggio C# e la nota relativa alla proposta sull'"Istruzione using basata su criteri" e "dichiarazioni using".

Vedi anche