Sim, Dispose
será chamado. É chamado assim que a execução sai do escopo do using
bloco, independentemente do meio que levou para sair do bloco, seja o fim da execução do bloco, uma return
instrução ou uma exceção.
Como @Noldorin corretamente aponta, o uso de um using
bloco no código é compilado em try
/ finally
, Dispose
sendo chamado no finally
bloco. Por exemplo, o seguinte código:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
efetivamente se torna:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
Portanto, como finally
tem garantia de execução após o try
bloco ter concluído a execução, independentemente de seu caminho de execução, Dispose
é garantido que será chamado, não importa o quê.
Para obter mais informações, consulte este artigo do MSDN .
Adendo:
apenas uma pequena advertência a ser adicionada: como Dispose
é garantido que será chamado, é quase sempre uma boa ideia garantir que Dispose
nunca lance uma exceção ao implementar IDisposable
. Infelizmente, existem algumas classes na biblioteca central que fazer lance em determinadas circunstâncias, quando Dispose
é chamado - Eu estou olhando para você, Proxy WCF Serviço de Referência / Cliente! - e quando isso acontece, pode ser muito difícil rastrear a exceção original se ela Dispose
foi chamada durante o desenrolamento de uma pilha de exceções, uma vez que a exceção original é engolida em favor da nova exceção gerada pela Dispose
chamada. Pode ser enlouquecedoramente frustrante. Ou isso é frustrantemente enlouquecedor? Um dos dois. Talvez ambos.