2012-01-17 14 views
7

Eventuali duplicati:
Catching specific vs. generic exceptions in c#Gestione delle eccezioni C#, quale clausola catch da usare?

Ecco un metodo di esempio

private static void outputDictionaryContentsByDescending(Dictionary<string, int> list) 
{ 
    try 
    { 
     //Outputs entire list in descending order 
     foreach (KeyValuePair<string, int> pair in list.OrderByDescending(key => key.Value)) 
     { 
      Console.WriteLine("{0}, {1}", pair.Key, pair.Value); 
     } 
    } 
    catch (Exception e) 
    { 
     MessageBox.Show(e.Message, "Error detected", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

Vorrei sapere che cosa clausola di eccezione per utilizzare parte solo Exception e se v'è un vantaggio nell'uso di clausole di cattura più specifiche.

Edit: O.k grazie a tutti

risposta

2

L'unica causa potenziale di un'eccezione che vedo nel tuo esempio è se list è nullo. OrderByDescending() dovrebbe restituire uno IEnumerable<> vuoto anziché un riferimento null.

Se ho letto che correttamente, potrebbe avere più senso per catturare NullReferenceException:

try 
{ 
... 
} catch (NullReferenceException exception) 
{ 
    MessageBox.Show(...); 
} 

Tuttavia, questo dipende davvero alle esigenze della vostra applicazione. Se la tua intenzione è solo di avvisare l'utente o di registrare tutte le eccezioni, prendere la classe Exception va bene. Se avete bisogno di un trattamento speciale per i diversi tipi di eccezioni - come l'invio di un avviso e-mail invece di registrazione del messaggio - allora ha senso utilizzare specifici tipi di eccezione:

try 
{ 
} 
catch(NullReferenceException e) 
{ 
//... 
} 
catch(StackOverflowException e) 
{ 
//... 
} 
catch(Exception e) 
{ 
/// generic exception handler 
} 
+0

Se 'list' è nullo,' outputDictionaryContentsByDescending' dovrebbe lanciare 'ArgumentNullException' –

7

Facendo singoli tipi di eccezioni nella vostra dichiarazione vi permetterà di gestire ogni in modo diverso.

Una regola generale per Exception può essere utile per la registrazione e il risanamento delle eccezioni, ma non è la soluzione migliore per gestire effettivamente le eccezioni dalle quali è possibile eseguire il ripristino.

try 
{ 
    // open a file specified by the user 
} 
catch(FileNotFoundException ex) 
{ 
    // notify user and re-prompt for file 
} 
catch(UnauthorizedAccessException ex) 
{ 
    // inform user they don't have access, either re-prompt or close dialog 
} 
catch(Exception ex) 
{ 
    Logger.LogException(ex); 
    throw; 
} 
4

Si dovrebbe veramente solo intercettare le eccezioni che si sono aspettano che codice può buttare. In questo modo, se lancia qualcosa che non ti aspetti, potrebbe essere qualcosa di critico; qualcosa che dovrebbe bolla lo stack di chiamate e possibilmente crash l'applicazione; o qualcosa a cui non hai pensato.

Ad esempio, è possibile gestire lo IOException s generato dal codice I/O in modo da poter ritrasmettere il problema all'utente. Tuttavia, le stesse operazioni potrebbero generare qualcosa di più critico, ad esempio AccessViolationException. In questo caso, potresti volere che il programma termini o gestire il problema in un modo diverso.

Generico gestione delle eccezioni è consentito solo davvero nei casi in cui non si cura di ciò che si è verificato l'errore, e successivamente non lo vogliono influenzare il resto del processo.

1

Dal momento che si tratta di un dizionario .. poi si vuole guardare a queste 2 eccezioni

  • La chiave di KeyValuePair è un riferimento null (Nothing in Visual Basic).

  • ArgumentException Un elemento con la stessa chiave esiste già nel Dizionario (TKey, TValue).

    KekValuePair Exception questo è preso dal sito MSDN

+0

Oh grazie per questo non lo sapeva elencato le possibili excpetions su MSDN – Elliot678

0

Utilizzare il tipo di eccezione che ci si potrebbe aspettare, ma ancora non in grado di prevenire e che si può adeguatamente gestire. Lascia che qualcos'altro bolla in qualche luogo che potrebbe aspettarsi o in grado di gestirlo.

Nel tuo caso, potrei aspettarti di imbattersi in un NullReferenceException se il dizionario è nullo. Ma non lo prenderei. Questo è qualcosa che posso convalidare contro invece

if (dictionary != null) 

Quindi non v'è alcun motivo per consentire un'eccezione accada ancora. Non utilizzare mai eccezioni per il flusso di controllo e convalidare contro cause note.

0

Alcune classi/metodi generano eccezioni diverse, a seconda dell'errore. Ad esempio, potresti utilizzare la classe File per scrivere dati in un file. È possibile scrivere più istruzioni Catch per i tipi di eccezione da cui è possibile eseguire il ripristino e un catch Eccezionale generico per registrare e rendere invisibili qualsiasi cosa non possa essere ripristinata.

0

Utilizzando l'eccezione si rilevano tutte le eccezioni. Di te usi IOException o StackOverflowException, ti verranno rilevati solo errori di quel tipo.

uno StackOverflowException catturato da un Exception ancora tenere lo stesso messaggio, Analisi dello stack ecc

1

Si dovrebbe sempre intercettare le eccezioni con una più specifici classe possibile.

Se sai cosa fare se un file è bloccato, ma consideri tutti gli altri errori imprevisti e impossibili da gestire, dovresti prendere lo System.IO.IOException e gestire l'errore. Dovresti solo prendere Exception (o solo catch {) per uscire con grazia.

2

Quale eccezione da utilizzare dipende realmente dal codice nel blocco try. In generale, vuoi rilevare le eccezioni con cui puoi fare qualcosa e lasciare che le eccezioni di cui non hai potere si spostino su livelli elevati del tuo codice in cui puoi eseguire un'azione che fa da allora. Uno degli errori più comuni che vedo le persone è cercare di individuare errori che non hanno capacità di gestire.

ad esempio

Void ChoseFile() 
{ 
    try 
    { 
     string FileName = GetInputFile() 
    }  
    catch(InvalidFileSelectedException ex) 
    { 
     //In this case we have some application specific exception 
     //There may be a business logic failure we have some ability 
     //to infomr the user or do an action that makes sense 
    } 
    catch(FileNotFoundException exfilenot found) 
    { 
     //In this case we can do somthing different the the above 
    } 
    catch(Exception) 
    { 
     //Normal I would not use this case we have an error we don't know what to do 
     //with. We may not have a usefull action. At best we can log this exception        
     // and rethrow it to a higher level of the application that can inform the user 
     // fail the attempted action. Catching here would only suppress the failure. 
     } 

} 
0

gestione delle eccezioni filosofia io sono sicuro che potete trovare molte altre filosofie

Codice sulla difensiva. Le eccezioni di cattura sono più costose che evitare l'errore in primo luogo.

Non prendere un'eccezione e seppellirla non trattandola. Puoi passare molte ore a cercare di trovare un errore che è stato soppresso.

Registra errori di registro. Questo aiuta ad analizzare il problema.È possibile verificare se più di un utente ha lo stesso problema Preferisco un database per la registrazione, ma sono adatti anche un file flat o il registro eventi. La soluzione di database è più semplice da analizzare ma può introdurre errori aggiuntivi.

Se l'errore è dovuto a dati errati inseriti dall'utente, informare l'utente del problema e consentire di riprovare. Consentire sempre una via di fuga se non è possibile risolvere il problema.

Cattura l'errore il più vicino possibile alla sorgente Questa potrebbe essere una procedura di database, un metodo in un livello di accesso ai dati (DAL) o in un'altra posizione.

La gestione dell'eccezione è diversa dalla cattura. Potrebbe essere necessario rilanciare l'eccezione in modo che possa essere gestita più in alto nello stack o nell'interfaccia utente.

Il richiamo dell'eccezione può essere effettuato in almeno due modi. da solo non altera la pila. ex throw altera o aggiunge allo stack senza alcun beneficio.

A volte è meglio non rilevare un'eccezione, ma piuttosto farla esplodere.

Se si scrivono servizi (Web o Windows) che non dispongono di un'interfaccia utente (UI), è necessario registrare sempre l'errore. Ancora, questo è così che qualcuno può analizzare il log o il file di database per determinare cosa sta succedendo.

Vuoi sempre che qualcuno sappia che si è verificato un errore.

Avere molte istruzioni catch per un blocco try può rendere il vostro codice più difficile da mantenere, specialmente se la logica nei blocchi catch è complessa. Invece, codice in modo difensivo.

Ricorda che puoi provare a catturare blocchi all'interno dei blocchi di cattura.

Inoltre, non dimenticare di utilizzare il blocco finally dove appropriato. Per esempio, chiudendo le connessioni al database, o handle di file, ecc

HTH Harv