Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Essa semana estava revendo um trecho do ARDA (https://github.com/DXBrazil/Arda) e os primeiros issues e pull requests estavam relacionados com o tratamento de exceção. Por coincidência, nessa mesma semana, fui perguntado sobre as melhores práticas de Exceptions sobre como e quando usar.
Comecei olhando a documentação do C# sobre o try-catch-finally.
Try-catch-finally
/en-us/dotnet/csharp/language-reference/keywords/try-catch-finally
Nesse artigo, há o seguinte trecho de código:
Então, pergunto:
O que há de errado nesse exemplo?
Embora a linguagem permita a construção e a documentação confirma que é possível, sigo o pensamento de que a sintaxe try..catch..finally não deveria existir no C#. Na minha opinião, não se deve usar try-catch-finally. Essa é uma afirmação forte e, antes de que alguém se desespere, deixo explicar meu ponto de vista.
Por que não existe “finally” no C++?
Você sabia que a linguagem C++ suporta exceções e somente a construção try-catch? Não existe finally!
https://www.stroustrup.com/bs_faq2.html#finally
Why doesn't C++ provide a "finally" construct?
Resposta do Bjarne Stroustrup:
Because C++ supports an alternative that is almost always better: The "resource acquisition is initialization" technique (TC++PL3 section 14.4).
A linguagem do C++ adota o padrão de Resource Acquisition is Initialization (RAII) . Em outras palavras, os recursos devem ser desalocados dentro do destrutor das classes, dispensando o uso do finally.
Use try-catch
Quando lidamos com exceção, tratamos as exceptions através de blocos try-catch.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch
Não tem segredo: as exceções são capturadas pelo bloco catch para tratamento do erro.
Use try-finally
A linguagem suporta a construção try-finally para liberar os recursos alocados.
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally
Diferente do C++, o garbage collector do C# (.NET) é não-determinístico. Por isso, sempre garanta que os recursos são liberados no momento certo através do finally.
Não use try-catch-finally
A construção try-catch-finally mistura dois propósitos distintos no mesmo código. Por isso, deixe claro a intenção e use a sintaxe adequada com os blocos:
- try-catch: Tratar os erros e exceções
- try-finally: Liberar explicitamente os recursos
Reescrevi o trecho anterior usando try-catch-finally e, ao invés de melhorar o código, parece que ficou mais confuso:
Nesse momento, é natural encapsular o trecho do código de leitura de arquivo dentro de outra função. Veja como o código fica mais claro:
A função ReadFileBlock gerencia o objeto File, fazendo a alocação de recurso e liberando no finally.
Compare como ficou muito melhor que a versão try-catch-finally.
Conclusão
Nesse artigo, apresentei a ideia de evitar o try-catch-finally porque essa construção mistura os conceitos de tratamento de exceção e liberação de recurso. Ao invés disso, recomendo que use try-catch ou try-finally.
Comments
- Anonymous
November 07, 2017
A conclusão ficou estranha. Está escrito: "... apresentei a ideia de 'não' evitar o try-catch-finally".- Anonymous
November 13, 2017
Errei! Ja vou corrigir. Obrigado!
- Anonymous