Edição: Eu concordo com outras pessoas que estão dizendo que, a partir do C # 6.0, filtros de exceção agora são um caminho perfeitamente correto:catch (Exception ex) when (ex is ... || ex is ... )
Só que eu ainda odeio o layout de uma linha longa e pessoalmente colocaria o código da seguinte maneira. Eu acho que isso é tão funcional quanto estético, pois acredito que melhora a compreensão. Alguns podem discordar:
catch (Exception ex) when (
ex is ...
|| ex is ...
|| ex is ...
)
ORIGINAL:
Eu sei que estou um pouco atrasado para a festa aqui, mas fumaça sagrada ...
Indo direto ao assunto, esse tipo de duplicata uma resposta anterior, mas se você realmente deseja executar uma ação comum para vários tipos de exceção e manter a coisa toda limpa e arrumada no escopo do método, por que não usar apenas um lambda / encerramento / função embutida para fazer algo como o seguinte? Quero dizer, as chances são muito boas de que você acabe percebendo que deseja apenas tornar esse fechamento um método separado que possa ser utilizado em todo o lugar. Mas será super fácil fazer isso sem alterar o restante do código estruturalmente. Direita?
private void TestMethod ()
{
Action<Exception> errorHandler = ( ex ) => {
// write to a log, whatever...
};
try
{
// try some stuff
}
catch ( FormatException ex ) { errorHandler ( ex ); }
catch ( OverflowException ex ) { errorHandler ( ex ); }
catch ( ArgumentNullException ex ) { errorHandler ( ex ); }
}
Não posso deixar de me perguntar ( aviso: um pouco de ironia / sarcasmo pela frente) por que diabos vamos a todo esse esforço para basicamente substituir apenas o seguinte:
try
{
// try some stuff
}
catch( FormatException ex ){}
catch( OverflowException ex ){}
catch( ArgumentNullException ex ){}
... com uma variação louca desse próximo cheiro de código, quero dizer exemplo, apenas para fingir que você está salvando algumas teclas.
// sorta sucks, let's be honest...
try
{
// try some stuff
}
catch( Exception ex )
{
if (ex is FormatException ||
ex is OverflowException ||
ex is ArgumentNullException)
{
// write to a log, whatever...
return;
}
throw;
}
Porque certamente não é automaticamente mais legível.
É verdade que deixei as três instâncias idênticas /* write to a log, whatever... */ return;
do primeiro exemplo.
Mas esse é o meu ponto. Vocês já ouviram falar de funções / métodos, certo? A sério. Escreva uma ErrorHandler
função comum e, como, chame-a de cada bloco catch.
Se você me perguntar, o segundo exemplo (com as palavras if
- is
chave e ) é significativamente menos legível e, ao mesmo tempo, significativamente mais suscetível a erros durante a fase de manutenção do seu projeto.
A fase de manutenção, para qualquer um que seja relativamente novo em programação, abrangerá 98,7% ou mais da vida útil geral do seu projeto, e o pobre coitado que faz a manutenção certamente será alguém que não seja você. E há uma chance muito boa de que eles gastem 50% do seu tempo no trabalho amaldiçoando seu nome.
E, é claro, o FxCop late para você e, portanto, você também deve adicionar um atributo ao seu código que seja exatamente o que está relacionado ao programa em execução, e existe apenas para solicitar ao FxCop que ignore um problema que, em 99,9% dos casos, é totalmente correto na sinalização. E, desculpe, posso estar enganado, mas esse atributo "ignorar" acaba realmente compilado no seu aplicativo?
Colocar o if
teste inteiro em uma linha o tornaria mais legível? Acho que não. Quero dizer, eu tive outro programador argumentar veementemente, há muito tempo, que colocar mais código em uma linha o faria "correr mais rápido". Mas é claro que ele estava nojento. Tentando explicar a ele (com uma cara séria - o que foi desafiador) como o intérprete ou compilador dividiria essa longa linha em instruções discretas de uma instrução por linha - essencialmente idêntico ao resultado se ele tivesse ido em frente e apenas tornou o código legível em vez de tentar enganar o compilador - não teve nenhum efeito nele. Mas eu discordo.
Quanto menos legível fica quando você adiciona mais três tipos de exceção, daqui a um mês ou dois? (Resposta: fica muito menos legível).
Um dos principais pontos, na verdade, é que a maior parte do ponto de formatar o código-fonte textual que todos nós estamos vendo todos os dias é torná-lo muito, muito óbvio para outros seres humanos o que realmente está acontecendo quando o código é executado. Como o compilador transforma o código-fonte em algo totalmente diferente e não se importava com o seu estilo de formatação de código. Então, tudo em uma linha também é uma droga também.
Apenas dizendo...
// super sucks...
catch( Exception ex )
{
if ( ex is FormatException || ex is OverflowException || ex is ArgumentNullException )
{
// write to a log, whatever...
return;
}
throw;
}