196 votes

Pourquoi utiliser finally en C# ?

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

3 votes

Que voulez-vous dire par "laisser ouvert" ?

5 votes

Et que voulez-vous dire par "(presque)" ?

1 votes

Ce n'est pas vrai du tout. L'idée est que si une erreur se produit, le contrôle passera au bloc catch. La seule possibilité d'exécuter tout le code est qu'aucune exception ne se produise, et dans ce cas, pourquoi utiliser le try/catch ?

419voto

Kevin Pang Points 16019

Le code contenu dans un bloc final sera exécuté, qu'il y ait ou non une exception. Cela s'avère très pratique lorsqu'il s'agit de certaines fonctions de gestion courante que vous devez toujours exécuter, comme la fermeture des connexions.

Maintenant, je suis deviner votre question est de savoir pourquoi vous devriez le faire :

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

Quand vous pouvez le faire :

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

alwaysDoThis();

La réponse est que, bien souvent, le code contenu dans l'instruction catch relancera une exception ou sortira de la fonction en cours. Dans ce dernier cas, l'appel "alwaysDoThis() ;" ne s'exécutera pas si le code contenu dans l'instruction catch émet un retour ou lance une nouvelle exception.

3 votes

Hmm. Très similaire à ce que j'ai dit, mais plus clair et plus précis. Définitivement +1.

49 votes

Cela s'applique aussi à "return" à l'intérieur du bloc try{}.

6 votes

En fait, elle s'applique même sans bloc catch{} (juste try/finally, en laissant les exceptions surgir)

62voto

Noldorin Points 67794

La plupart des avantages de l'utilisation de try-finally ont déjà été soulignés, mais j'ai pensé ajouter 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 (i.e. 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'une en utilisant Le bloc est souvent préférable dans ce cas.

2 votes

C'est littéralement la seule raison pour laquelle j'utilise enfin

12voto

Bob The Janitor Points 5526

À chaque fois que vous utilisez des requêtes de code non gérées comme des lecteurs de flux, des requêtes de données, etc., et que vous voulez attraper l'exception, utilisez try catch finally et fermez le flux, le lecteur de données, etc. dans le finally, si vous ne le faites pas, la connexion ne sera pas fermée en cas d'erreur.

 SqlConnection myConn = new SqlConnection("Connectionstring");
        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, alors utilisez

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

et l'objet de connexion sera éliminé automatiquement s'il y a une erreur, mais vous ne capturez pas l'erreur.

2 votes

Dispose() fermera également() la connexion, il n'est pas nécessaire d'appeler les deux. Close() ne fait PAS Dipose(), vous pouvez rouvrir la connexion.

0 votes

Sympa, merci d'avoir mentionné l'utilisation. Je serais obligé de répondre, sinon.

11voto

Matt Briggs Points 20291

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

7voto

David Alpert Points 2305

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 que votre try..catch indépendamment du fait que votre bloc d'essai ait ou non déclenché une exception.

Cela le rend parfait pour des choses comme la libération de ressources, les connexions à des bases de données, les manipulations de fichiers, etc.

3 votes

Tous ces exemples sont généralement mieux servis par un bloc d'utilisation, mais cela n'enlève rien à votre réponse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X