Dando continuação a serie de posts sobre o C# 8, vamos conhecer uma feature chamada de Using declarations. A declaração using é muito útil quando queremos dar um Dispose no nosso objeto ao término da sua utilização, dentro de determinado escopo. Internamente ele encapsula um bloco try/finally chamando Dispose no finally.
Hoje utilizamos a declaração using da seguinte forma:
public static StringBuilder ReadFile()
{
var fileContent = new StringBuilder();
using (var file = new FileStream("input.txt", FileMode.OpenOrCreate))
{
using (var Stream = new StreamReader(file))
{
var str = Stream.ReadToEnd();
fileContent.Append(str);
}
}
return fileContent;
}
No exemplo acima, quando a execução da aplicação atingir o return, os objetos file e Stream já terão sido descartados, pois saiu do seu escopo delimitador e os objetos não mais serão acessados.
Na nova versão, o mesmo código seria escrito da seguinte forma:
public static StringBuilder ReadFile()
{
using var file = new FileStream("input.txt", FileMode.OpenOrCreate);
using var Stream = new StreamReader(file);
var str = Stream.ReadToEnd();
var fileContent = new StringBuilder();
fileContent.Append(str);
return fileContent;
}
Internamente, seu funcionamento é o mesmo, inserindo using na frente da declaração da variável, garantirá que esta será descartada ao final do escopo, ou seja do método. Qual a vantagem então? A vantagem está na simplicidade, menos linhas, menos chaves e consequentemente menos indentação e mais foco no que realmente importa.
Um ponto importante nessa nova abordagem é não confundir com o Garbage Collector e os Finalizers. Esses dois são utilizados de forma não-determinística, ou seja, não sabemos exatamente quando ocorrerá, – já que chamar o GC.Collect não é legal – pois existe uma série de fatores que são considerados na hora de chamar o GC . Já no using, sabemos exatamente onde ele irá descartar os objetos apesar da supressão das chaves.