EDIT: concordo con gli altri che stanno dicendo che, a partire da C # 6.0, i filtri delle eccezioni sono ora un modo perfetto per andare:catch (Exception ex) when (ex is ... || ex is ... )
Tranne il fatto che odio ancora il layout a una riga lunga e che definirei il codice come segue. Penso che sia tanto funzionale quanto estetico, poiché credo che migliora la comprensione. Alcuni potrebbero non essere d'accordo:
catch (Exception ex) when (
ex is ...
|| ex is ...
|| ex is ...
)
ORIGINALE:
So di essere un po 'in ritardo alla festa qui, ma fumo santo ...
Passando direttamente all'inseguimento, questo tipo di duplica una risposta precedente, ma se vuoi davvero eseguire un'azione comune per diversi tipi di eccezione e mantenere tutto pulito e ordinato nell'ambito di un metodo, perché non usare semplicemente un lambda / chiusura / funzione in linea per fare qualcosa di simile al seguente? Voglio dire, è molto probabile che finirai per capire che vuoi solo rendere quella chiusura un metodo separato che puoi utilizzare ovunque. Ma sarà super facile farlo senza cambiare strutturalmente il resto del codice. Giusto?
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 ); }
}
Non posso fare a meno di chiedermi ( avvertimento: un po 'di ironia / sarcasmo davanti) perché mai fare tutto questo sforzo per sostituire semplicemente quanto segue:
try
{
// try some stuff
}
catch( FormatException ex ){}
catch( OverflowException ex ){}
catch( ArgumentNullException ex ){}
... con qualche variazione folle di questo odore di codice successivo, intendo esempio, solo per far finta che stai salvando alcune sequenze di tasti.
// 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;
}
Perché certamente non è automaticamente più leggibile.
Concesso, ho lasciato le tre identiche istanze di /* write to a log, whatever... */ return;
del primo esempio.
Ma è una specie del mio punto. Avete sentito parlare di funzioni / metodi, giusto? Sul serio. Scrivi un comuneErrorHandler
funzione e, come, chiamala da ciascun blocco catch.
Se me lo chiedi, il secondo esempio (con il if
eis
parole chiave ) è significativamente meno leggibile e contemporaneamente significativamente più soggetto a errori durante la fase di manutenzione del tuo progetto.
La fase di manutenzione, per chiunque sia relativamente nuovo nella programmazione, comprenderà il 98,7% o più della durata complessiva del progetto e il povero schmuck che fa la manutenzione sarà quasi sicuramente qualcuno diverso da te. E c'è una buona probabilità che trascorrano il 50% del loro tempo sul lavoro maledicendo il tuo nome.
E ovviamente FxCop ti abbaia e quindi devi anche aggiungere un attributo al tuo codice che ha esattamente zip a che fare con il programma in esecuzione, ed è lì solo per dire a FxCop di ignorare un problema che nel 99,9% dei casi è totalmente corretto nella segnalazione. E, scusa, potrei sbagliarmi, ma l'attributo "ignora" non viene effettivamente compilato nella tua app?
Metterebbe l'intero if
test su una riga lo renderebbe più leggibile? Io non la penso così. Voglio dire, molto tempo fa un altro programmatore sosteneva con veemenza che mettere più codice su una riga lo avrebbe fatto "correre più veloce". Ma ovviamente era completamente pazzo. Cercare di spiegargli (con una faccia seria - il che era una sfida) come l'interprete o il compilatore avrebbero spezzato quella lunga riga in discrete istruzioni una per riga - sostanzialmente identiche al risultato se fosse andato avanti e ha appena reso leggibile il codice invece di provare a fare il furbo del compilatore - non ha avuto alcun effetto su di lui. Ma sto divagando.
Quanto meno leggibile si ottiene quando si aggiungono altri tre tipi di eccezione, tra un mese o due? (Risposta: diventa molto meno leggibile).
Uno dei punti principali, in realtà, è che la maggior parte del punto di formattazione del codice sorgente testuale che tutti noi guardiamo ogni giorno è quello di rendere davvero, davvero ovvio agli altri esseri umani ciò che sta realmente accadendo quando il codice viene eseguito. Perché il compilatore trasforma il codice sorgente in qualcosa di completamente diverso e non potrebbe importare di meno del tuo stile di formattazione del codice. Quindi anche tutto on-one-one-line fa schifo.
Sto solo dicendo ...
// super sucks...
catch( Exception ex )
{
if ( ex is FormatException || ex is OverflowException || ex is ArgumentNullException )
{
// write to a log, whatever...
return;
}
throw;
}