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 instrução using 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 declaração de uso, que foi introduzida no C# 8.0, não requer 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 IDisposable objeto é limitado a um único método, você deve declará-lo e instanciá-lo na using instrução ou using declaração. A using declaração chama o Dispose método no objeto da maneira correta quando ele sai do escopo. A using instrução faz com que o próprio objeto saia do escopo assim que Dispose é chamado. Dentro do using bloco, o objeto é somente leitura e não pode ser modificado ou reatribuído. Uma variável declarada com uma using declaração é somente leitura. Se o objeto for implementado IAsyncDisposable em vez de IDisposable, qualquer using formulário chamará o DisposeAsync e awaits o retornado ValueTask. Para obter mais informações sobre IAsyncDisposable, consulte Implementar um método DisposeAsync.

Ambos os using formulários garantem 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, chamando Dispose (ou DisposeAsync) em um finally bloco; na verdade, é assim que a using instrução e a using declaração são traduzidas 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 de instrução mais using recente se traduz em código semelhante. O try bloco é aberto onde a variável é declarada. O finally bloco é adicionado no fechamento do bloco delimitar, normalmente no final de um método.

Para obter mais informações sobre a try-finally instrução, consulte o artigo try-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 tipada implicitamente (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 sintaxe de declaração introduzida com o 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