A leitura do artigo de Eric Lippert sobre exceções foi definitivamente uma revelação sobre como eu deveria abordar as exceções, tanto como produtor quanto como consumidor. No entanto, ainda estou lutando para definir uma diretriz sobre como evitar exceções irritantes.
Especificamente:
- Suponha que você tenha um método Save que pode falhar porque a) alguém modificou o registro antes de você ou b) o valor que você está tentando criar já existe . Essas condições são esperadas e não excepcionais; portanto, em vez de lançar uma exceção, você decide criar uma versão Try do seu método, TrySave, que retorna um booleano indicando se a gravação foi bem-sucedida. Mas, se falhar, como o consumidor saberá qual foi o problema? Ou seria melhor retornar uma enumeração indicando o resultado, tipo Ok / RecordAlreadyModified / ValueAlreadyExists? Com integer.TryParse, esse problema não existe, pois há apenas um motivo pelo qual o método pode falhar.
- O exemplo anterior é realmente uma situação irritante? Ou lançar uma exceção nesse caso seria a maneira preferida? Eu sei que é assim que é feito na maioria das bibliotecas e estruturas, incluindo a estrutura de entidades.
- Como você decide quando criar uma versão Try do seu método versus fornecer uma maneira de testar antecipadamente se o método funcionará ou não? Atualmente, estou seguindo estas diretrizes:
- Se houver a chance de uma condição de corrida, crie uma versão Try. Isso evita a necessidade de o consumidor capturar uma exceção exógena. Por exemplo, no método Save descrito anteriormente.
- Se o método para testar a condição praticamente fizer tudo o que o método original, crie uma versão Try. Por exemplo, integer.TryParse ().
- Em qualquer outro caso, crie um método para testar a condição.