Dove mettere le dichiarazioni try-catch [chiuso]

0

Ho la seguente istruzione di codice che chiama una classe separata.

if (newOrEdit.Equals("New"))
{
    try
    {
        BusinessLayer.InsertOperator(operatorDetails);
    }
    catch (Exception)
    {
        MessageBox.Show("Error unable to insert details.");
    }

}

Questo chiama un metodo semplice che tenta di inserire l'operatore.

Ho visto lo stesso metodo fatto come segue

if (newOrEdit == "New")
{
    if (Business.insertNewUser(userDetails))
    {
        this.Close();
    }
    else
    {
        MessageBox.Show("Unable to insert new user", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        this.Close();
    }
}

Ora questo metodo accetta un ritorno booleano e all'interno del metodo ha il trucco try all'interno della business class.

Quale dei seguenti è migliore e perché?

    
posta Inkey 19.10.2015 - 15:59
fonte

4 risposte

7

La migliore pratica generale è usare solo eccezioni su eccezioni . Il processo di creazione di un'eccezione e il suo lancio è generalmente molto costoso, quindi dovrebbe essere evitato per cose che possono fallire con operazioni abbastanza normali.

La validazione è un buon esempio di questo. Le persone invieranno immissioni di rifiuti tutto il tempo. Questo è un errore, ma non eccezionale , quindi non utilizzare eccezioni.

Quindi se l'inserimento di un nuovo utente dovrebbe quasi sempre riuscire (a parte qualche circostanza eccezionale, come un fulmine che uccide la tua rete), provare / catturare va bene. Se l'inserimento di un nuovo utente potrebbe fallire, allora il successo sarebbe meglio.

    
risposta data 19.10.2015 - 16:11
fonte
5

La gestione delle eccezioni tende ad essere un'operazione abbastanza costosa, quindi se stai scrivendo il codice che viene chiamato e puoi gestirlo con garbo, dovresti.

Se stai scrivendo il codice che può avere una condizione di errore, valuta se l'errore che stai gestendo è recuperabile. Sarebbe piuttosto duro forzare un'eccezione a essere lanciata per un semplice errore di immissione dei dati.

    
risposta data 19.10.2015 - 16:11
fonte
1

Ci sono due comuni usi impropri del meccanismo di eccezione: in primo luogo, è usarlo come un canale di informazione evento standard (che non è quello per cui è stato progettato); secondo, è quello di "inghiottire" le eccezioni in un modo che nasconde i problemi da te.

Il risultato di una di queste operazioni è che l'eccezione / errore viene gestita in un punto non appropriato nel codice. Quante volte hai ricevuto un'eccezione lanciata, ma la causa è un po 'di codice lungo la catena? Spesso! (se lo hai fatto per un po 'di tempo!)

Ad esempio: hai una piccola classe yourPackage.util.ConvertDate. Fa un'invocazione di riflessione sul tuo input e ti dà qualche valore derivato, ma se uno dei tuoi valori di input per un metodo interno privato è nullo, genererà un IllegalArgumentException o forse un InvocationTargetException. In un mondo ideale, quel metodo sarebbe definito come "lancia IllegalArgumentException" e quell'eccezione sarebbe "gonfiata" al livello successivo. In alberi di eccezioni ben progettati, quell'eccezione continuerebbe a passare attraverso le dichiarazioni "getta" fino a quando non ha colpito la stessa riga di codice che imposta il valore inutilizzabile!

Il concetto qui è di fare in modo che l'eccezione si bolla nel punto esatto del codice in cui puoi ottenere il miglior recupero.

Un altro esempio: si ha una routine di inserimento del database che non riesce perché c'è un valore nullo nei parametri PreparedStatement, per un campo non nullable nel database. Getta una SQLException. Se si "inghiotte" quell'eccezione e si passa un valore di ritorno falso booleano per mostrare che un record non è stato inserito nel DB, (e probabilmente si ignora il valore restituito) e successivamente quando si scopre che il proprio oggetto non esiste , non hai modo di sapere se fosse a causa di un valore nullo, perché c'era qualcosa di ALTRO in errore con quel valore (cioè mettendo una stringa in un campo BIGINT) o che c'era un errore di sintassi nella tua istruzione SQL o anche se tu Ho perso momentaneamente la connessione di rete al database! Quando hai gestito l'eccezione verso il basso in cui non avevi la possibilità di fare una scelta pertinente nella questione e RISOLVI, allora ti sei procurato un enorme mal di testa per il debug in seguito.

    
risposta data 19.10.2015 - 16:42
fonte
1

Questa non è una domanda in bianco e nero che potrebbe ricevere una risposta come "A is always better" o "Avoid B a tutti i costi", ma generalmente:

Il modo preferito sono le eccezioni, non i risultati di stato.

(E per motivi di coerenza è meglio evitare la conversione tra i due se non si ha una buona ragione. In questo caso, non vedo.)

I frammenti di codice che hai postato sono codice di livello superiore. Quando si scrive codice di primo livello, (dove può essere sensato cercare di intercettare eccezioni), l'uso di eccezioni può sembrare complicato e inutilmente prolisso rispetto all'utilizzo dei risultati di stato. Tuttavia, è necessario considerare che il codice di livello superiore non è l'unico codice che costituisce un'applicazione non banale; questo metodo InsertOperator() può rappresentare (o può essere invocato da) un albero di chiamate a diversi livelli, costituito da centinaia di righe di codice, in cui ogni metodo richiamato deve restituire un risultato di stato e ogni chiamante deve essere Assicurati di controllare questo risultato dello stato e prendere le misure appropriate se non ha successo. Abbastanza spesso i programmatori dimenticano quella roba; è quando avvengono errori difficili da trovare.

Con le eccezioni, il codice al di sotto del livello superiore che non ha bisogno di gestire un'eccezione non deve contenere un blocco try-catch e se deve occuparsi di eccezioni solo allo scopo di lasciare le cose come trovato, può semplicemente usare try-finally invece di try-catch . Questo in genere si traduce in un codice molto più semplice, molto più strutturato, molto più comprensibile e molto più gestibile rispetto al tipo di codice spaghetti che abbiamo usato per scrivere nei giorni dei codici risultato, prima che le eccezioni fossero state inventate.

Naturalmente, come sempre, ci possono essere buoni motivi per scegliere i codici risultato invece delle eccezioni. Come hanno già indicato altre risposte, se qualcosa deve accadere così spesso da non essere considerato una "situazione eccezionale", allora forse non dovrebbe essere espresso come un'eccezione e la penalità legata al lancio di un'eccezione potrebbe essere proibitiva . Ma nel tuo caso, non riuscire ad aggiungere un "utente" o un "operatore" sembra una situazione abbastanza grave ed eccezionale da giustificare proprio questo: un'eccezione.

    
risposta data 19.10.2015 - 21:38
fonte

Leggi altre domande sui tag