C # Nested Prova le istruzioni oi metodi Catch?

Semplice domanda sulle migliori pratiche.

Se nidifichi, prova a prendere le dichiarazioni o usa solo i metodi.

Ad esempio, se hai un metodo che apre un file funziona e chiude il file, dovresti aprire e chiudere all’esterno del try catch, o piuttosto chiudere nel blocco finally.

Ora se il tuo metodo aperto fallisce, il metodo dovrebbe affermare correttamente? Quindi dovrebbe essere il vostro involucro che in un blocco catch try o dovrebbe essere chiamato da un altro metodo, che a sua volta come un blocco catch try?

Nel contesto di un metodo che apre un file, utilizzerei un’istruzione using rispetto a un try catch. L’istruzione using garantisce che Dispose venga chiamato se si verifica un’eccezione.

using (FileStream fs = new FileStream(file, FileMode.Open)) { //do stuff } 

fa la stessa cosa di:

 FileStream fs; try { fs = new FileStream(file, FileMode.Open); //do Stuff } finally { if(fs!=null) fs.Dispose(); } 

Ora che abbiamo lambda e inferenza di tipo e altre cose, c’è un idioma che è comune in altre lingue che ora ha molto senso in C #. Il tuo esempio riguardava l’apertura di un file, l’esecuzione di qualcosa e la sua chiusura. Bene, ora puoi creare un metodo di supporto che apra un file e si occupi anche di assicurarti di chiudere / smaltire / ripulire, ma invoca un lambda che fornisci per la parte “fai da te”. Ciò ti aiuterà a ottenere le complicate operazioni di try / catch / finally dispose / cleanup direttamente in un unico posto, e quindi a utilizzarle più e più volte.

Ecco un esempio:

 public static void ProcessFile(string filePath, Action fileProcessor) { File openFile = null; try { openFile = File.Open(filePath); // I'm making this up ... point is you are acquiring a resource that needs to be cleaned up after. fileProcessor(openFile); } finally { openFile.Close(); // Or dispose, or whatever. } } 

Ora, i chiamanti di questo metodo non devono preoccuparsi di come aprire il file o chiuderlo / eliminarlo. Possono fare qualcosa del genere:

 Helpers.ProcessFile("C://somefile.txt", f => { while(var text = f.ReadLine()) { Console.WriteLine(text); } }); 

Questa è una domanda di stile, ma per me cerco di non avere più di un livello di try / catch / finalmente nidificazione in un unico metodo. Nel momento in cui premi un tentativo annidato, hai quasi certamente violato il principio operativo 1 funzione = 1 e dovresti utilizzare un secondo metodo.

Dipende da cosa stai provando a fare, ma nella maggior parte dei casi, i try / catch annidati sono un segno di una funzione troppo complessa (o di un programmatore che non sa come funzionano le eccezioni!).

Nel caso del file aperto, utilizzerei un titolare IDisposable e una clausola using, e quindi rinunciare alla necessità di qualsiasi try / catch esplicito.

Che ne dici di un codice correlato che non appartiene necessariamente a una funzione separata del suo diritto? Questo sarebbe quindi corretto?

 try { // Part 1 Code Here try { // Part 2 Code Here } catch (Exception ex) { // Error from Part 2 } } catch (Exception ex) { // Error from Part 1 } 

La maggior parte delle volte rompevo i blocchi annidati try / catch in funzioni. Ma a volte ho scritto codice per catturare e registrare tutte le eccezioni non rilevate generate dalla mia applicazione. Ma cosa succede se il codice di registrazione fallisce? Quindi ho ancora un altro tentativo / aggirare questo solo per impedire all’utente di vedere la finestra di dialogo di eccezione non gestita. NET predefinito. Ma anche questo codice potrebbe essere facilmente refactored in funzioni invece di blocchi try / catch nidificati.

 try { try { DoEverything(); } catch (Exception ex) { // Log the exception here } } catch (Exception ex) { // Wow, even the log is broken ... } 
 //create a switch here and set it to 0 try { DoChunk1(); //looks good. set the switch to 1 } catch (Exception ex) { // Log the exception here } 

// controlla l’interruttore, se è ancora zero a questo punto, puoi interrompere qui il tuo programma; altrimenti resetta lo switch a zero ed esegui la tua successiva dichiarazione catch. totalmente d’accordo con la loro rottura come menzionato sopra

prova {DoChunk2 (); //sembra buono. imposta l’interruttore su 1} catch (Exception ex) {// Registra l’eccezione qui}

 try { ---- } catch { try { --- } catch { --- } }