Pourquoi utiliser finalement en C #?

Tout ce qui se trouve à l’intérieur des blocs est exécuté (presque) toujours, alors quelle est la différence entre y enfermer du code ou le laisser fermé?

Le code à l’intérieur d’un bloc finally sera exécuté, qu’il y ait ou non une exception. Ceci est très pratique quand il s’agit de certaines fonctions de gestion dont vous avez besoin pour toujours exécuter comme des connexions de fermeture.

Maintenant, je suppose que votre question est la suivante:

try { doSomething(); } catch { catchSomething(); } finally { alwaysDoThis(); } 

Quand tu peux faire ça:

 try { doSomething(); } catch { catchSomething(); } alwaysDoThis(); 

La réponse est que beaucoup de fois le code dans votre instruction catch renverra une exception ou sortira de la fonction en cours. Avec ce dernier code, le “alwaysDoThis ();” call ne s’exécutera pas si le code contenu dans l’instruction catch émet un retour ou lance une nouvelle exception.

La plupart des avantages de l’utilisation de try-finally ont déjà été soulignés, mais je pensais append celui-ci:

 try { // Code here that might throw an exception... if (arbitraryCondition) { return true; } // Code here that might throw an exception... } finally { // Code here gets executed regardless of whether "return true;" was called within the try block (ie regardless of the value of arbitraryCondition). } 

Ce comportement le rend très utile dans diverses situations, en particulier lorsque vous devez effectuer un nettoyage (disposer de ressources), bien qu’un bloc d’ utilisation soit souvent préférable dans ce cas.

Parce que finalement sera exécuté même si vous ne gérez pas une exception dans un bloc catch.

chaque fois que vous utilisez des demandes de code non gérées, telles que des lecteurs de stream, des demandes de firebase database, etc. et vous voulez attraper l’exception alors utilisez try catch Finalement et fermez le stream, le lecteur de données, etc. dans le fichier final, si ce n’est pas le cas, la connexion n’est pas fermée,

  SqlConnection myConn = new SqlConnection("Connectionssortingng"); try { myConn.Open(); //make na DB Request } catch (Exception DBException) { //do somehting with exception } finally { myConn.Close(); myConn.Dispose(); } 

si vous ne voulez pas attraper l’erreur, utilisez

  using (SqlConnection myConn = new SqlConnection("Connectionssortingng")) { myConn.Open(); //make na DB Request myConn.Close(); } 

et l’object de connexion sera automatiquement éliminé en cas d’erreur, mais vous ne capturerez pas l’erreur

finally , comme dans:

 try { // do something risky } catch (Exception ex) { // handle an exception } finally { // do any required cleanup } 

est une opportunité garantie d’exécuter du code après votre bloc try..catch , que votre bloc try..catch une exception ou non.

Cela le rend parfait pour des choses comme la libération de ressources, les connexions db, les descripteurs de fichiers, etc.

Enfin, les instructions peuvent être exécutées même après le retour.

 private int myfun() { int a = 100; //any number int b = 0; try { a = (5 / b); return a; } catch (Exception ex) { Response.Write(ex.Message); return a; } // Response.Write("Statement after return before finally"); -->this will give error "Syntax error, 'try' expected" finally { Response.Write("Statement after return in finally"); // --> This will execute , even after having return code above } Response.Write("Statement after return after finally"); // -->Unreachable code } 

Disons que vous devez redéfinir le curseur sur le pointeur par défaut au lieu d’un curseur en attente (sablier). Si une exception est levée avant de définir le curseur, et ne bloque pas complètement l’application, vous risquez de vous retrouver avec un curseur déroutant.

Parfois, vous ne voulez pas gérer une exception (pas de bloc catch), mais vous voulez un code de nettoyage à exécuter.

Par exemple:

 try { // exception (or not) } finally { // clean up always } 

Le bloc finally est utile pour nettoyer toutes les ressources allouées dans le bloc try et pour exécuter tout code qui doit être exécuté même s’il existe une exception. Le contrôle est toujours passé au bloc finally indépendamment de la manière dont le bloc try se termine.

En utilisant un bloc finally , vous pouvez nettoyer toutes les ressources allouées dans un bloc try et exécuter du code même si une exception se produit dans le bloc try . En règle générale, les instructions d’un bloc finally exécutées lorsque le contrôle laisse une instruction try. Le transfert de contrôle peut se produire à la suite d’une exécution normale, de l’exécution d’une break, continue, goto, or return , ou de la propagation d’une exception hors de l’instruction try .

Dans une exception gérée, le bloc finally associé est garanti pour être exécuté. Cependant, si l’exception n’est pas gérée, l’exécution du bloc finally dépend de la manière dont l’opération de déroulement de l’exception est déclenchée. Cela dépend à son tour de la configuration de votre ordinateur. Pour plus d’informations, voir Traitement des exceptions non gérées dans le CLR .

Généralement, lorsqu’une exception non gérée met fin à une application, le fait que le bloc finally soit ou non exécuté n’est pas important. Cependant, si vous avez des instructions dans un bloc finally qui doivent être exécutées même dans cette situation, une solution consiste à append un bloc catch à l’instruction try-finally . Vous pouvez également intercepter l’exception qui pourrait être générée dans le bloc try d’une instruction try-finally plus haut dans la stack d’appels. Autrement dit, vous pouvez intercepter l’exception dans la méthode qui appelle la méthode qui contient l’instruction try-finally , ou dans la méthode qui appelle cette méthode, ou dans n’importe quelle méthode de la stack d’appels. Si l’exception n’est pas interceptée, l’exécution du bloc finally dépend du choix du système d’exploitation de déclencher une opération de décompression.

 public class ThrowTestA { static void Main() { int i = 123; ssortingng s = "Some ssortingng"; object obj = s; try { // Invalid conversion; obj contains a ssortingng, not a numeric type. i = (int)obj; // The following statement is not run. Console.WriteLine("WriteLine at the end of the try block."); } finally { // To run the program in Visual Studio, type CTRL+F5. Then // click Cancel in the error dialog. Console.WriteLine("\nExecution of the finally block after an unhandled\n" + "error depends on how the exception unwind operation is sortingggered."); Console.WriteLine("i = {0}", i); } } // Output: // Unhandled Exception: System.InvalidCastException: Specified cast is not valid. // // Execution of the finally block after an unhandled // error depends on how the exception unwind operation is sortingggered. // i = 123 } 

Dans l’exemple suivant, une exception de la méthode TryCast est interceptée dans une méthode située plus haut dans la stack d’appels. C #

 public class ThrowTestB { static void Main() { try { // TryCast produces an unhandled exception. TryCast(); } catch (Exception ex) { // Catch the exception that is unhandled in TryCast. Console.WriteLine ("Catching the {0} exception sortingggers the finally block.", ex.GetType()); // Restore the original unhandled exception. You might not // know what exception to expect, or how to handle it, so pass // it on. throw; } } public static void TryCast() { int i = 123; ssortingng s = "Some ssortingng"; object obj = s; try { // Invalid conversion; obj contains a ssortingng, not a numeric type. i = (int)obj; // The following statement is not run. Console.WriteLine("WriteLine at the end of the try block."); } finally { // Report that the finally block is run, and show that the value of // i has not been changed. Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i); } } // Output: // In the finally block in TryCast, i = 123. // Catching the System.InvalidCastException exception sortingggers the finally block. // Unhandled Exception: System.InvalidCastException: Specified cast is not valid. } 

Je vais expliquer l’utilisation de finalement avec une exception de lecteur de fichier

  • sans utiliser finalement
 try{ StreamReader strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); StreamReader.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } 

Dans l’exemple ci-dessus, si le fichier appelé Data.txt est manquant, une exception sera levée et sera traitée, mais l’ instruction appelée StreamReader.Close(); ne sera jamais exécuté.
En raison de ces ressources associées au lecteur n’a jamais été publié.

  • Pour résoudre le problème ci-dessus, nous utilisons finalement
 StreamReader strReader = null; try{ strReader = new StreamReader(@"C:\Ariven\Project\Data.txt"); Console.WriteLine(strReader.ReadeToEnd()); } catch (Exception ex){ Console.WriteLine(ex.Message); } finally{ if (strReader != null){ StreamReader.Close(); } } 

Bonne codage 🙂

Remarque: “@” est utilisé pour créer une chaîne verbatim , afin d’éviter toute erreur de “séquence d’échappement non reconnue”. Le symbole @ signifie lire cette chaîne littéralement et n’interprète pas les caractères de contrôle autrement.

Ahh … je pense que je vois ce que vous dites! Il m’a fallu une seconde … vous vous demandez pourquoi le placer dans le bloc final plutôt que après le bloc final et complètement en dehors du try-catch-finally.

Par exemple, cela peut être dû au fait que vous arrêtez l’exécution si vous lancez une erreur, mais que vous souhaitez toujours nettoyer les ressources, telles que les fichiers ouverts, les connexions à la firebase database, etc.

Enfin bloquer

Si vous avez une ou plusieurs instructions à exécuter avant de quitter la structure Try , utilisez un bloc Finally . Un bloc Finally est utile pour exécuter tout code qui doit être exécuté même s’il existe une exception. Le contrôle est transmis au bloc Finally , quelle que soit la façon dont le bloc TryCatch termine. Le contrôle passe au bloc Finally juste avant qu’il ne sorte de la structure TryCatch . Cela est vrai même si une exception se produit n’importe où dans la structure Try . Le code d’un bloc Finally s’exécute même si votre code rencontre une instruction Return dans un bloc Try ou Catch .

Il n’est pas valide de transférer explicitement l’exécution dans un bloc Finally .

Le transfert de l’exécution d’un bloc Finally n’est pas valide, sauf par une exception.

Le stream de contrôle du bloc Finally est soit après le bloc Try ou Catch.

 [1. First Code] [2. Try] [3. Catch] [4. Finally] [5. After Code] 

avec Exception 1> 2> 3> 4> 5 si 3 a une déclaration de retour 1> 2> 3> 4

sans exception 1> 2> 4> 5 si 2 a une déclaration de retour 1> 2> 4