È una cattiva pratica tornare dall'interno di un blocco try catch finalmente?


128

Quindi stamattina mi sono imbattuto in un codice simile a questo:

try
{
    x = SomeThingDangerous();
    return x;
}
catch (Exception ex)
{
    throw new DangerousException(ex);
}
finally
{
    CleanUpDangerousStuff();
}

Ora questo codice si compila bene e funziona come dovrebbe, ma non sembra giusto tornare da un blocco try, specialmente se alla fine è associato.

Il mio problema principale è cosa succede se finalmente viene generata un'eccezione? Hai una variabile restituita ma anche un'eccezione da affrontare ... quindi sono interessato a sapere cosa pensano gli altri di tornare da un blocco try?


13
Un vantaggio di questo stile è che non devi dichiarare xal di fuori del tryblocco. Puoi tenere la sua dichiarazione vicino al suo uso.
David R Tribble,

Risposte:


169

No, non è una cattiva pratica. Mettere returndove ha senso migliora la leggibilità e la manutenibilità e semplifica la comprensione del codice. Non dovresti preoccuparti poiché il finallyblocco verrà eseguito se returnviene rilevata un'istruzione.


19

L'ultimo verrà eseguito indipendentemente da cosa, quindi non importa.


9
No, in realtà, non è solo una connessione, ci sono alcune eccezioni chiamate eccezioni asincrone come StackOverflowException, ThreadAbortException e OutOfMemoryException che potrebbero impedire l'esecuzione del blocco finally. Informazioni sulle aree di esecuzione vincolate per la gestione di questi scenari.
Mehrdad Afshari,


14

Personalmente, eviterei questo tipo di codifica poiché non mi va di vedere le dichiarazioni di ritorno prima delle dichiarazioni finalmente.

La mia mente è semplice ed elabora le cose in modo piuttosto lineare. Pertanto, quando passo attraverso il codice per l'esecuzione a secco, avrò la tendenza a pensare che una volta che posso raggiungere la dichiarazione di ritorno, tutto ciò che segue non importa che ovviamente è piuttosto sbagliato in questo caso (non che influenzerebbe la dichiarazione di ritorno ma quali potrebbero essere gli effetti collaterali).

Quindi, vorrei organizzare il codice in modo che la dichiarazione di ritorno appaia sempre dopo le dichiarazioni di fine.


9

Questo potrebbe rispondere alla tua domanda

Cosa succede veramente in un tentativo {return x; } infine {x = null; } dichiarazione?

Dalla lettura di questa domanda sembra che tu possa avere un altro tentativo di catturare la struttura nell'istruzione finally se pensi che potrebbe generare un'eccezione. Il compilatore capirà quando restituire il valore.

Detto questo, potrebbe essere meglio ristrutturare il tuo codice comunque solo per non confonderti in seguito o per qualcun altro che potrebbe non essere a conoscenza di questo.


hmmm molto interessante. Ciò significa che è sicuro, ma significa che dovrebbe essere evitato?
lomaxx,

3
Personalmente penso che renda la leggibilità del tuo codice un po 'difficile e che da sola sarebbe sufficiente a farmi capire un altro modo per strutturare il codice. Ma in realtà è solo una preferenza personale.
Spencer Ruport il

3
Tendo ad essere d'accordo con le tue preferenze personali :)
lomaxx,

Penso che il ritorno vada bene dove si trova. Il metodo restituirà il valore, a meno che non venga generata un'eccezione; non importa se l'eccezione si presenta nel codice di cleanup.
Lawrence Dol,

Nota che la restrizione sul ritorno da finalmente non è presente in Java (ma penso che la restrizione sia buona - complimenti a C #).
Lawrence Dol,

5

Funzionalmente non c'è differenza.

Tuttavia c'è una ragione per non farlo. Metodi più lunghi con diversi punti di uscita sono spesso più difficili da leggere e analizzare. Ma questa obiezione ha più a che fare con le dichiarazioni di rimpatrio che con le catture e infine i blocchi.



3

Nel tuo esempio in entrambi i casi è equivalente, non sarei nemmeno sorpreso se il compilatore generasse lo stesso codice. Se si verifica un'eccezione nel blocco finally, si verificano gli stessi problemi se si inserisce l'istruzione return in blocco o al di fuori di essa.

La vera domanda è stilisticamente qual è la migliore. Mi piace scrivere i miei metodi in modo che ci sia una sola dichiarazione di ritorno, in questo modo è più facile vedere il flusso fuori dal metodo, ne consegue che mi piace anche mettere l'ultima dichiarazione di ritorno, quindi è facile vedere che è la fine del metodo e questo ciò che restituisce.

Penso che con l'istruzione return così ben posizionata come l'ultima istruzione, è meno probabile che altre vengano e cospargano più dichiarazioni return in altre parti del metodo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.