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.