Blocos de Using

Blocos de Using

O que são, para que servem e do que se alimentam? Entendendo o básico pela visão de um graduando.

Estava eu fazendo um trabalho final de uma disciplina de banco de dados e surgiram algumas dúvidas enquanto desbravava esse terreno. A ideia era fazer um software usando .NET que integre um banco de dados no SQL Server. Sendo bem leigo e mergulhando nas estruturas de dados utilizadas para fazer a consulta no banco, percebi que havia using para lá e using para cá, mas afinal, para que serve? E por que se repete tanto?

O que faz?

O using é feito para criar um bloco que, ao final da execução, libera os recursos utilizados, simples assim.

No código abaixo, podemos observar em funcionamento um try-finally. Nele, podemos ver melhor como funciona o using, que, no final das contas, após ser compilado, será traduzido para um try-finally com dispose. Nesse bloco de código, podemos observar que o programa tenta executar o que é solicitado e, assim que tem sucesso, descarta os recursos utilizados.

var fileStream = new FileStream("example.txt", FileMode.Open);
try
{
    var reader = new StreamReader(fileStream);
    try
    {
        string content = reader.ReadToEnd();
        Console.WriteLine(content);
    }
    finally
    {
        reader.Dispose();
    }
}
finally
{
    fileStream.Dispose();
}

// código do chatGPT 30/05/2024

O bloco using é um resumo sintático do try-finally, como podemos ver abaixo.

using (var fileStream = new FileStream("example.txt", FileMode.Open))
{
    using (var reader = new StreamReader(fileStream))
    {
        string content = reader.ReadToEnd();
        Console.WriteLine(content);
    } // reader.Dispose()
} // fileStream.Dispose()

Ok, parece fácil, qual a duvida?

Assim como tivemos um try-finally aninhado, tivemos também um using aninhado. Mas por quê? Se os recursos já vão ser descartados no fim do primeiro using, qual a intenção de usar outro? Eu realmente devo digitar 3 linhas de código a mais para chamar SqlConnection, SqlCommand e SqlDataReader? Parece pouco, mas os recursos são descartáveis, então, basicamente, toda vez que eu precisar fazer uma query, vou ter que digitar using várias vezes. Isso é perda de tempo, não?

Meio que não... no caso de aninhar os blocos, apesar de não tornar mais simples, torna mais legível e mais seguro. Aninhando os blocos, você consegue ver melhor as dependências e garantir que os recursos vão ser dispensados na sequência correta. Trabalhando com o SQL Server, fica fácil de entender isso.

No código abaixo, podemos enxergar bem a dependência de cada namespace. Precisamos do cmd para o reader e precisamos da connection para o cmd. Além de organizar a utilização desses recursos, o bloco vai garantir que o reader sofra o dispose antes do command ou da connection.

private void populateGrupoVenda()
{
    string connectionString = DatabaseManager.connectionString;
    string query = "SELECT nomeGrupo FROM gruposVenda";

    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        try
        {
            connection.Open();
            using (SqlCommand cmd = new SqlCommand(query, connection))
            {
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        comboBoxGrupoVenda.Items.Add(reader["nomeGrupo"].ToString());
                    }
                } // reader.Dispose()
            } // cmd.Dispose()
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error:" + ex.Message);
        }
    } // connection.Dispose()
}

// o código de exemplo é utilizado para popular uma combobox com os dados de uma tabela do SQL Server

Dito isso

Dito isso, o using é um mecanismo de segurança, gerenciamento das estruturas de dados e legibilidade. Consigo fazer as mesmas coisas sem aninhar os blocos? No meu caso, sim, um programa simples para um trabalho final de uma disciplina de Banco de Dados. Porém, para um código bem feito e robusto, aninhar os blocos de using pode ser essencial.