Instrução using (Referência de C#)

Fornece uma sintaxe conveniente que garante o uso correto de objetos IDisposable. A partir do C# 8,0, a using instrução garante o uso correto de IAsyncDisposable objetos.

Exemplo

O exemplo a seguir mostra como usar a instrução using.

string manyLines=@"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

using (var reader = new StringReader(manyLines))
{
    string? item;
    do {
        item = reader.ReadLine();
        Console.WriteLine(item);
    } while(item != null);
}

A partir do C# 8,0, você pode usar a seguinte sintaxe alternativa para a using instrução que não exige chaves:

string manyLines=@"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

using var reader = new StringReader(manyLines);
string? item;
do {
    item = reader.ReadLine();
    Console.WriteLine(item);
} while(item != null);

Comentários

File e Font são exemplos de tipos gerenciados que acessam recursos não gerenciados (nesse caso, identificadores de arquivo de caso e contextos de dispositivo). Há muitos outros tipos de recursos não gerenciados e tipos de biblioteca de classes que os encapsula. Todos esses tipos devem implementar a IDisposable interface ou a IAsyncDisposable interface.

Quando o tempo de vida de um objeto IDisposable é limitado a um único método, você deve declará-lo e instanciá-lo na instrução using. A instrução using chama o método Dispose no objeto da forma correta e (quando você o usa como mostrado anteriormente) ele também faz com que o objeto em si saia do escopo assim que Dispose é chamado. Dentro do using bloco, o objeto é somente leitura e não pode ser modificado ou reatribuído. Se o objeto for implementado IAsyncDisposable em vez de IDisposable , a using instrução chamará o DisposeAsync e awaits o retornado ValueTask . Para obter mais informações sobre IAsyncDisposable o, consulte implementar um método DisposeAsync.

A using instrução garante que Dispose (ou DisposeAsync ) seja chamado mesmo se ocorrer uma exceção dentro do using bloco. Você pode obter o mesmo resultado colocando o objeto dentro de um try bloco e, em seguida Dispose , chamando (ou DisposeAsync ) em um finally bloco; na verdade, é assim que a using instrução é convertida pelo compilador. O exemplo de código anterior se expande para o seguinte código em tempo de compilação (observe as chaves extras para criar o escopo limitado para o objeto):

string manyLines=@"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

{
    var reader = new StringReader(manyLines);
    try {
        string? item;
        do {
            item = reader.ReadLine();
            Console.WriteLine(item);
        } while(item != null);
    } finally
    {
        reader?.Dispose();
    }
}

A sintaxe mais recente da using instrução é convertida em código semelhante. O try bloco é aberto onde a variável é declarada. O finally bloco é adicionado ao fechamento do bloco delimitador, normalmente no final de um método.

Para obter mais informações sobre a try - finally instrução, consulte o artigo Experimente-finally .

Várias instâncias de um tipo podem ser declaradas em uma única using instrução, conforme mostrado no exemplo a seguir. Observe que você não pode usar variáveis de tipo implícito ( var ) ao declarar várias variáveis em uma única instrução:

string numbers=@"One
Two
Three
Four.";
string letters=@"A
B
C
D.";

using (StringReader left = new StringReader(numbers),
    right = new StringReader(letters))
{
    string? item;
    do {
        item = left.ReadLine();
        Console.Write(item);
        Console.Write("    ");
        item = right.ReadLine();
        Console.WriteLine(item);
    } while(item != null);
}

Você pode combinar várias declarações do mesmo tipo usando a nova sintaxe introduzida com C# 8 também, conforme mostrado no exemplo a seguir:

string numbers=@"One
Two
Three
Four.";
string letters=@"A
B
C
D.";

using StringReader left = new StringReader(numbers),
    right = new StringReader(letters);
string? item;
do {
    item = left.ReadLine();
    Console.Write(item);
    Console.Write("    ");
    item = right.ReadLine();
    Console.WriteLine(item);
} while(item != null);

Você pode instanciar o objeto de recurso e, em seguida, passar a variável para a using instrução, mas essa não é uma prática recomendada. Nesse caso, após o controle sair do bloco using, o objeto permanecerá no escopo, mas provavelmente não terá acesso a seus recursos não gerenciados. Em outras palavras, ele não é mais totalmente inicializado. Se você tentar usar o objeto fora do bloco using, corre o risco de causar o lançamento de uma exceção. Por esse motivo, é melhor instanciar o objeto na using instrução e limitar seu escopo ao using bloco.

string manyLines=@"This is line one
This is line two
Here is line three
The penultimate line is line four
This is the final, fifth line.";

var reader = new StringReader(manyLines);
using (reader)
{
    string? item;
    do {
        item = reader.ReadLine();
        Console.WriteLine(item);
    } while(item != null);
}
// reader is in scope here, but has been disposed

Para obter mais informações sobre como descartar objetos IDisposable, veja Usando objetos que implementam IDisposable.

Especificação da linguagem C#

Para obter mais informações, consulte A instrução using na Especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.

Confira também