web-dev-qa-db-fra.com

try / catch + using, syntaxe correcte

Laquelle:

using (var myObject = new MyClass())
{
   try
   {
      // something here...
   }
   catch(Exception ex)
   {
      // Handle exception
   }
}

OR

try
{
   using (var myObject = new MyClass())
   {
      // something here...
   }
}
catch(Exception ex)
{
   // Handle exception
}
175
Xaqron

Je préfère le second. Peut également piéger des erreurs relatives à la création de l'objet.

88
Jonathan Wood

Comme un bloc using n’est qu’une simplification syntaxique de try/finally ( [(# ~ ~] msdn [~ # ~] ), personnellement, j’allais avec ce qui suit, même si je doute que ce soit significativement différent que votre deuxième option:

MyClass myObject = null;
try {
  myObject = new MyClass();
  //important stuff
} catch (Exception ex) {
  //handle exception
} finally {
  if(myObject is IDisposable) myObject.Dispose();
}
34
chezy525

Ça dépend. Si vous utilisez Windows Communication Foundation (WCF), using(...) { try... } ne fonctionnera pas correctement si le proxy de l'instruction using est en état d'exception, c'est-à-dire que la suppression de ce proxy provoquera une autre exception.

Personnellement, je crois en l’approche de manipulation minimale, c’est-à-dire ne gérer que les exceptions dont vous avez connaissance au moment de l’exécution. En d'autres termes, si vous savez que l'initialisation d'une variable dans using peut générer une exception particulière, je l'enveloppe avec try-catch. De même, si, dans using body, quelque chose peut se produire qui n’est pas directement liée à la variable dans using, je l’enveloppe alors avec un autre try pour cette exception particulière. J'utilise rarement Exception dans mes catches.

Mais j’aime bien IDisposable et using bien que j’ai peut-être un parti pris.

19
Schultz9999

Si votre instruction catch doit accéder à la variable déclarée dans une instruction using, l'intérieur est votre seule option.

Si votre déclaration catch a besoin de l'objet référencé dans using avant d'être éliminé, alors votre choix est de l'intérieur.

Si votre instruction catch prend une action de durée inconnue, telle que l'affichage d'un message à l'utilisateur, et que vous souhaitez disposer de vos ressources avant que cela ne se produise, l'extérieur est votre meilleure option.

Chaque fois que j'ai un scénario similaire à celui-ci, le bloc try-catch utilise généralement une méthode différente, en amont de la pile d'appels. Il n’est pas typique pour une méthode de savoir comment gérer les exceptions qui se produisent dans cette méthode.

Donc, ma recommandation générale est à l'extérieur, bien à l'extérieur.

private void saveButton_Click(object sender, EventArgs args)
{
    try
    {
        SaveFile(myFile); // The using statement will appear somewhere in here.
    }
    catch (IOException ex)
    {
        MessageBox.Show(ex.Message);
    }
}
19

Les deux sont une syntaxe valide. Cela dépend vraiment de ce que vous voulez faire: si vous voulez intercepter des erreurs liées à la création/la suppression d’un objet, utilisez la seconde. Sinon, utilisez le premier.

9
Smashery

Il y a une chose importante que je vais appeler ici: La première va not attraper toute exception résultant de l'appel du constructeur MyClass.

6
Madhur Ahuja

Si l'objet que vous initialisez dans le bloc Using () peut générer une exception, vous devez utiliser la deuxième syntaxe, sinon la valeur est également valide.

Dans mon scénario, je devais ouvrir un fichier et je passais filePath dans le constructeur de l'objet que j'étais en train d'initialiser dans le bloc Using () et il pouvait y avoir une exception si le chemin filePath était incorrect ou vide. Donc, dans ce cas, la deuxième syntaxe est logique.

Mon exemple de code: -

try
{
    using (var obj= new MyClass("fileName.extension"))
    {

    }
}
catch(Exception ex)
{
     //Take actions according to the exception.
}
1
Ankur Arora