Meilleure pratique concernant le retour d’utilisation de blocs

Quelle est la meilleure pratique: renvoyer une valeur d’une méthode dans une instruction using ou déclarer une variable avant, la définir à l’intérieur et la renvoyer après?

 public int Foo() { using(..) { return bar; } } 

ou

 public int Foo() { var b = null; using(..) { b = bar; } return b; } 

Je préfère le premier exemple. Moins de variables, moins de lignes de code, plus facile à suivre, plus facile à gérer …

 public int Foo() { using(..) { return bar; } } 

En suivant le principe “less is more” (en réalité une variante de KISS ), l’ancien. Il y a moins de lignes de code à maintenir, pas de changement de sémantique ni de perte de lisibilité (ce style est sans doute plus facile à lire).

Utilisation de Statement – MSDN

L’instruction using garantit que Dispose est appelé même si une exception se produit pendant que vous appelez des méthodes sur l’object. Vous pouvez obtenir le même résultat en plaçant l’object dans un bloc try, puis en appelant Dispose dans un bloc finally. En fait, c’est ainsi que l’instruction using est traduite par le compilateur.

De l’ essay-enfin (référence C #)

finally est utilisé pour garantir l’exécution d’un bloc d’instruction quel que soit le mode de sortie du bloc try précédent.

Pour répondre à votre question, oui, vous pouvez revenir d’une déclaration using.

La seconde est nettement meilleure, et vous pouvez vérifier que cela fonctionne bien en écrivant un programme de test.

L’instruction using elle-même ne peut pas avoir de valeur, ce qui est une limitation. Supposons que vous ayez une méthode appelée Open qui retourne un FileStream ouvert et que vous voulez obtenir la longueur du fichier:

 Console.WriteLine(Open().Length); 

Le problème est que vous ne supprimez pas FileStream . Donc, vous devez écrire (semblable à votre exemple):

 long length; using (FileStream file = Open()) length = file.Length; Console.WriteLine(length); 

Mais avec une méthode d’extension simple , vous pouvez écrire ceci à la place:

 Console.WriteLine(Open().Use(file => file.Length)); 

Nice et soigné, et le FileStream est correctement éliminé.

Aucune raison de ne pas le faire puisque cette instruction using traduit par un bloc try...finally et que la partie finally est exécutée (même via un retour ou une exception non gérée).

Cela dépend vraiment des préférences personnelles. Vous trouverez des arguments des deux côtés de cette clôture. Moi-même, je privilégie l’option 1: revenir dès que possible. Je crois que cela exprime mieux l’intention du code; Il n’y a aucune raison de restr plus longtemps que nécessaire. Si vous avez terminé tout votre travail, revenez.

Parfois, vous aurez plusieurs points de retour possibles et un travail “de fin de méthode” (journalisation, nettoyage) pouvant vous conduire à une seule instruction de retour. Rien de grave à cela, mais vous pouvez souvent gérer ces situations dans des blocs ou avec des aspects de la programmation orientée aspect.

Je me sens mieux

 public int Foo() { using(..) { return bar; } } 

Une chose qui nous vient à l’esprit lorsque nous utilisons cette méthode est que nous retournons entre deux utilisations. Ainsi, l’object (que nous avons emballé dans l’utilisation de) sera supprimé, la réponse est oui car une instruction using est simplement le mélange try / Enfin bloc, il est correct de revenir d’un bloc try aussi. L’expression de retour sera évaluée, puis le bloc finally sera exécuté, et la méthode retournera alors.Alors, allez-y 🙂