IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Try Catch Finally et Return


Sujet :

C#

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Points : 218
    Points
    218
    Par défaut Try Catch Finally et Return
    Bonjour,

    ptite question...

    pourquoi on ne peut pas mettre de return dans un finally ?...

    et puis, si on fait ça :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    bool retour;
    try
    {
        //....
        retour = true;
    }
    catch
    {
        //...
        retour = false;
    }
    return retour;
    est-ce que c'est correct?
    est-ce qu'on va toujours passer par le return?...

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Points : 909
    Points
    909
    Par défaut
    La clause finally est destinée à effectuer des traitements, qu'une exception ait été lancée ou non, et donc elle ne peut pas retourner une valeur...
    Ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    try { instruction1}
    catch (NullReferenceException e) { instruction2 }
    finally { instruction3 }
    Si instruction1 ne lance pas d'exception, on effectuera instruction3 (après instruction1 bien sûr...)
    Si instruction1 lance une NullRefrenceException, on effectuera instruction2 puis instruction3.
    Si instruction1 lance une autre exception, on effectuera instruction3 avant de renvoyer l'exception au niveau supérieur => dans ce cas-là, puisqu'on lance une exception, on ne peut pas retourner de valeur avec un return !

    Avec un "catch" tout court, on intercepte toutes les exceptions, donc on devrait pouvoir, selon le contenu du bloc catch, être à peu près sûr (et encore, on ne sait jamais...) qu'aucune exception n'est "en attente d'être lancée" lorsqu'on passe dans bloc finally, mais ce n'est pas le but de ce bloc (et puis si jamais instruction2 lançait une exception, hein ?).


    Dans le code copié ici, oui, dans tous les cas on passera par le return !
    Sauf exception ou erreur inattendue, bien sûr...

  3. #3
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Deux petites questions subsidiaires :
    1) Je me suis toujours demandé si il y avait en pratique une différence (et laquelle) entre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    try { instruction1}
    catch (NullReferenceException e) { instruction2 }
    finally { instruction3 }
    et :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    try { instruction1}
    catch (NullReferenceException e) { instruction2 }
    { instruction3 }
    2)Si instruction 2 génére une exception, passe-t'on ou non dans le bloc finally ?
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 764
    Points : 909
    Points
    909
    Par défaut
    En cas d'exception non capturée par le catch (donc ici une exception non convertible -euh- "castable" -euh- comment on dit ? en NullReferenceException) :
    - dans le premier cas, on effectue instruction3 avant de renvoyer l'exception
    - dans le deuxième cas, on renvoie directement l'exception

    En l'absence d'exception, ou pour une exception bien prise en compte par le catch (donc ici une NullReferenceException) et si on ne lance pas d'exception dans le bloc catch, le comportement sera le même dans les deux cas...

    Voir ici par exemple

  5. #5
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Merci de cette réponse, en fait j'ai recopié "bétement" : j'avais en tête
    catch (Exception e) { instruction2 }

    Mais, du coup , je comprends mieux le pourquoi de la syntaxe try ... catch ... finally ...
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    499
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 499
    Points : 218
    Points
    218
    Par défaut
    autre petite question...

    on peut faire un return dans un catch?
    si on ne veut pas faire le reste dans le cas où une exception est levée...

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Bonjour.

    Je me permets de remonter ce vieux topic, car son titre est tres explicite, et j'aimerai completer le sujet :

    A quel moment s'execute le finally, si il y a un return dans le try?

    J'ai lu la chose suivante dans un article, et aimerai avoir confirmation pour etre sur d'avoir bien compris.

    Pour le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    try
    {
         return _mavar1 == _mavar2;
    }
    finally
    {
       _reader.Close();
    }
    j'ai lu que dans le try, au moment où on arrive sur le return:
    1)le IL Emitter évalue l'expression "_mavar1 == _mavar2" et stocke le résultat
    2)il execute le contenu de finally
    3) il fait un return avec le resultat de l'expression qu'il avait stocké.

    J'en déduit que si "_mavar1 == _mavar2" leve une exception
    1) il stocke l'exception
    2) execute le finally
    3) leve l'exception

    Est ce exact?

  8. #8
    Membre éclairé Avatar de ppphil
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    612
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2007
    Messages : 612
    Points : 685
    Points
    685
    Par défaut
    Ben je viens d'essayer ce petit bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    private bool TestTry()
        {
          int i = 0;
          int j = 34;
          try
          {
            return (j / i) == 0;
          }
          finally
          {
            MessageBox.Show("coucou");
          }      
        }
    Ben il m'envoie le messagebox avant de crasher

  9. #9
    Membre actif Avatar de brachior
    Homme Profil pro
    Doctorant
    Inscrit en
    Mai 2011
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2011
    Messages : 190
    Points : 293
    Points
    293
    Par défaut
    Le mot clé finally permet d'effectuer une suite d'instructions à coup sûr ...
    Elle s'effectue quoi qu'il arrive pendant ou a la fin du try ... catch ...
    C'est le dernier bloc exécuté du try ... catch ...

    Il est très utile et souvent employé pour effectuer des libérations ...
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    // declaration d'une socket
    try
    {
      // travail sur la socket
    }
    catch(MyException)
    {
      // gère d'éventuelles exceptions
    }
    finally
    {
      // quoi qu'il arrive, je ferme la socket ...
    }

  10. #10
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Citation Envoyé par brachior Voir le message
    C'est le dernier bloc exécuté du try ... catch ...
    Visiblement non si tu lis bien

  11. #11
    Membre actif Avatar de brachior
    Homme Profil pro
    Doctorant
    Inscrit en
    Mai 2011
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2011
    Messages : 190
    Points : 293
    Points
    293
    Par défaut
    Si tu parles de l'exception qui est levée après le finally ...
    Forcément qu'elle est levée après ...
    Sinon le finally ne pourrait s'exécuter

    Donc le finally est bien le dernier bloc exécuté avant de quitter le try ... catch,
    Et qu'importe la façon dont on le quitte (Exception, return, exit, ...)

  12. #12
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Il semble que personne n'avait répondu simplement à la question de base alors...

    Citation Envoyé par melleb Voir le message
    pourquoi on ne peut pas mettre de return dans un finally ?...
    Mettre un return dans le finally, alors que l'exception est supposée être renvoyée à la fin du bloc finally, équivaudrait à empêcher la levée de l'exception. Ceci est le rôle de catch, pas de finally.

    La bonne place pour le return est donc après finally. Soit une exception a été levée et elle est relancée après le finally et avant le return, soit tout s'est bien passé et on atteint le return.

  13. #13
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Merci donQuiche.

    c'est pour cette raison que j'ai demandé
    A quel moment s'execute le finally, si il y a un return dans le try?
    Mais en fait mon interrogation est :
    il y a t'il un piège si on place un return dans le try ou le catch? un effet de bord indésirable qui se produirait dans un cas particulier?

    C'est pour cette raison que je tente de comprendre précisément comment se comporte finally, dans quel ordre se passent les choses...

  14. #14
    Membre actif Avatar de brachior
    Homme Profil pro
    Doctorant
    Inscrit en
    Mai 2011
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2011
    Messages : 190
    Points : 293
    Points
    293
    Par défaut
    Citation Envoyé par DonQuiche Voir le message
    La bonne place pour le return est donc après finally.
    Je suis pas d'accord,
    Placer le return après le finally n'a pas vraiment d'utilité ...
    Du moins, en règle général, le finally sert à exécuter un bloc avant de quitter le try ... catch
    Et est souvent utiliser pour exécuter un bloc avant de quitter une méthode.
    Mettre le return après exprime qu'on gère les exceptions dans la méthode,
    Donc l'utilisation du finally n'est pas primordiale
    (enfin, c'est peut être à mon sens ^^)

    Citation Envoyé par giova_fr Voir le message
    C'est pour cette raison que je tente de comprendre précisément comment se comporte finally, dans quel ordre se passent les choses...
    finally est exécuter à la fin du bloc try ... catch, quelque soit sa fin (une levée d'exception, un return, bon déroulement, ...)

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 312
    Points : 411
    Points
    411
    Par défaut
    Le finally sert pour le cleanup et la remise en état des objets une fois l'instruction try/catch effectuée (typiquement fermer la connexion BDD).

    Les instructions de branchement, comme le return, sont a totalement proscrire dans le finally car ils cassent le fil d’exécution normal.

    Du moins, en règle général, le finally sert à exécuter un bloc avant de quitter le try ... catch
    En fait il sert a remettre en état ton contexte, que tu aie eu une exception, ou pas.

    Et est souvent utiliser pour exécuter un bloc avant de quitter une méthode.
    Non absolument pas.

    La bonne place pour le return est donc après finally. Soit une exception a été levée et elle est relancée après le finally et avant le return, soit tout s'est bien passé et on atteint le return.
    Exact.

    il y a t'il un piège si on place un return dans le try ou le catch? un effet de bord indésirable qui se produirait dans un cas particulier?
    Non pas de piège particulier, il faut cependant garder en tête que ton finally sera toujours exécuté APRES que ta variable 'return' soit affectée:

    The execution order is:

    Code before return statement is executed
    Expression in return statement is evaluated
    finally block is executed
    Result evaluated in step 2 is returned
    Voir ici :http://stackoverflow.com/questions/4...null-statement

  16. #16
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    The execution order is:

    Code before return statement is executed
    Expression in return statement is evaluated
    finally block is executed
    Result evaluated in step 2 is returned
    dans ce cas.
    Que le return soit dans le try, ou apres le finally, ca ne change rien, non?

    Alors pourquoi :

    Citation Envoyé par nah666 Voir le message
    Citation Envoyé par DonQuiche Voir le message
    La bonne place pour le return est donc après finally. Soit une exception a été levée et elle est relancée après le finally et avant le return, soit tout s'est bien passé et on atteint le return.
    Exact.


  17. #17
    Membre actif Avatar de brachior
    Homme Profil pro
    Doctorant
    Inscrit en
    Mai 2011
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2011
    Messages : 190
    Points : 293
    Points
    293
    Par défaut
    Citation Envoyé par nah666 Voir le message

    Du moins, en règle général, le finally sert à exécuter un bloc avant de quitter le try ... catch

    En fait il sert a remettre en état ton contexte, que tu aie eu une exception, ou pas.

    Et est souvent utiliser pour exécuter un bloc avant de quitter une méthode.

    Non absolument pas.
    Une méthode devrait être un code représentant une fonction simple, une brique d'un algorithme plus complexe.
    Pour moi une méthode qui procède à d'innombrable blocs d'exécution, est une méthode mal pensée ...
    C'est pourquoi, il est très rare pour moi de voir dans une méthode un try ... catch suivi d'autres blocs ...
    Ce qui insinue que le try ... catch débute et termine la méthode dans 90% des cas ...

    Ça reste ma vision ... Mais je tenais à expliquer le pourquoi de mes dires ^^

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 312
    Points : 411
    Points
    411
    Par défaut
    dans ce cas.
    Que le return soit dans le try, ou apres le finally, ca ne change rien, non?
    En fait si ça change :
    http://blogs.msdn.com/b/jmstall/arch...finally-2.aspx

    A préciser d'ailleurs qu'en .NET ca ne compile juste pas le return dans le finally (comme le GOTO d'ailleurs)

    In C#, this is just illegal. Returns are forbidden in finally clauses. This nicely just avoids the whole problem by refusing to let you write such potentially ambiguous and confusing code.

  19. #19
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    Le blog en question ne traite que le fait qu'un return est illégal dans un finally. Il ne parle pas de la différence entre un return dans le try, ou apres le finally. A moins que j'ai raté la marche?

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    312
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 312
    Points : 411
    Points
    411
    Par défaut
    Ah, mais le return dans le try ou même dans le catch ne pose pas de problème.
    (Ton finally sera toujours exécuté si présent).

    C'est uniquement le return dans le finally qui ne compile pas car il peut y avoir des trucs casse gueule, du genre je lance une autre exception dans mon catch, et mon finally fait un return => quesqui doit sortir de la fonction ?

    Après mettre ton return dans le try (et/ou le catch), ou a la fin de la fonction, dépend uniquement de ce que dois faire ta fonction et éventuellement des règles de codage des boites.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Try catch finally, flux best practice
    Par LittleBean dans le forum Langage
    Réponses: 4
    Dernier message: 13/08/2009, 13h45
  2. try catch finally
    Par Javamar dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 07/03/2009, 17h05
  3. Interrogation sur : Try.Catch.Finally
    Par Seth77 dans le forum C#
    Réponses: 7
    Dernier message: 16/09/2008, 11h22
  4. Réponses: 3
    Dernier message: 12/12/2006, 18h58
  5. Réponses: 13
    Dernier message: 03/08/2006, 16h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo