Qual é melhor, e quando: usando declaração ou chamar Dispose () em um IDisposable em C #?
-
06-07-2019 - |
Pergunta
Suponha que eu tenho o seguinte:
using(var ctx = DataContextFactory.Create(0))
{ ... Some code ... }
Porque não basta fazer o seguinte e perder um par de chaves:?
var ctx = DataContextFactory.Create(0);
ctx.Dispose();
Obrigado pelo conselho!
Solução
O primeiro é melhor. Ele garante que está disposto mesmo se uma exceção é lançada, e trata corretamente o caso em que Create(0)
retorna nulo (isto é, não tentar chamar Dispose()
em uma instância nula).
Outras dicas
A declaração using
é sempre melhor porque ...
- você não pode esquecer de chamar
Dispose()
, mesmo com a evolução de código em diferentes caminhos de código -
Dispose()
é chamado, mesmo se há uma exceção. Ele também verificanull
antes de chamarDispose()
, o que pode ser útil (supondo que você não está apenas chamandonew
).
Um não-óbvio (para mim, pelo menos) truque com using
é como você pode evitar assentamento excessiva quando você tem vários objetos descartáveis:
using (var input = new InputFile(inputName))
using (var output = new OutputFile(outputName))
{
input.copyTo(output);
}
O código formatador VS vai deixar as duas declarações que começam na mesma coluna.
Na verdade, em algumas situações, você nem tem que repetir a instrução usando ...
using (InputFile input1 = new InputFile(inputName1), input2 = new InputFile(inputName2))
No entanto, as restrições para declarar múltiplas variáveis ??na mesma linha se aplica aqui, então os tipos deve ser o mesmo e você não pode usar o tipo implícito var .
Onde você pode, uso using
pelas razões Marc cita. OTOH esta não é uma solução morte cerebral como às vezes a vida útil do objeto não pode ser definido como um escopo léxico para usá-lo razoavelmente.
O único lugar que você não quer usar um bloco usando é onde o objeto descartável tem como escopo fora da função. Neste caso, a classe deve implementar IDisposable e descartar o objeto em sua Dispose ().
A instrução usando lhe dá ótima sintaxe além de proteção exceção. Você não pode deixar a instrução usando sem chamar Dispose (que se traduz em um bloco, finalmente, com uma chamada para descarte). Em seu segundo cenário, se você tivesse uma exceção entre a Criação e o Dispose, você não chamaria dispor diretamente. Que não é um problema a menos que você estiver usando recursos não gerenciados, mas se você for, você vai vazar.