71 votes

Quand dois-je utiliser les blocs "using" en C# ?

Y a-t-il des cas particuliers où je devrais (ou ne devrais pas ?) utiliser des blocs "utilisant" ?

using(SomeType t = new SomeType()){
    ...
}

93voto

Scott Langham Points 17447

Certains objets nécessitent une action lorsque vous avez fini de les utiliser. C'est généralement le cas parce que l'objet utilise une ressource dont il faut se débarrasser. Par exemple, si vous avez un objet fichier de la classe File, et que cet objet ouvre un fichier du système de fichiers, le fichier dans le système de fichiers devra être refermé.

Si vous avez laissé l'objet file et oublié d'appeler file.Close(), il ne sera pas nettoyé jusqu'à ce que le Garbage Collector (GC) s'exécute et vérifie que rien n'utilise encore l'objet file. Le moment de l'exécution du Garbage Collector devrait être laissé à l'appréciation du Common Language Runtime (CLR). Si le GC ne s'exécute pas avant un certain temps après que vous ayez fini d'utiliser le fichier, ce dernier peut rester ouvert pendant une longue période. Cela peut poser un gros problème s'il y a beaucoup d'objets fichier, ou si quelque chose veut ouvrir un fichier, mais ne peut pas le faire parce que l'objet fichier que vous avez laissé est toujours là.

Pour résoudre ce problème, C# dispose de l'interface IDisposable. Celle-ci possède une méthode appelée Dispose. Les classes qui nécessitent un certain nettoyage implémentent cette méthode Dispose. Vous disposez ainsi d'une méthode standard pour nettoyer tous les objets qui utilisent des ressources. Il y a beaucoup de classes qui ont besoin d'être appelées Dispose. Le problème, c'est que le code est couvert d'appels à Dispose, et qu'il est difficile de les suivre parce que les endroits où vous avez créé l'objet et où vous appelez Dispose pour le nettoyer sont différents. Il faut donc beaucoup regarder dans le code et faire très attention à ce que les appels à Dispose soient faits au bon endroit.

Pour résoudre ce problème, C# a introduit le mot-clé "using". Vous pouvez mettre un mot-clé 'using' autour de l'endroit où vous créez un nouvel objet, et cela garantit que Dispose sera appelé pour vous. Il garantit que Dispose sera appelé quoi qu'il arrive... même si une exception est levée dans le corps de l'instruction using.

Vous devez donc utiliser "using" lorsque vous voulez être sûr qu'un objet qui alloue des ressources sera nettoyé.


using ne peut être utilisé que pour les objets qui sont déclarés sur la pile, c'est-à-dire dans une fonction. Elle ne fonctionne pas pour les objets qui sont déclarés comme membres d'une classe. Pour eux, vous devez appeler Dispose vous-même. Vous devrez peut-être implémenter Dispose dans votre classe afin qu'elle puisse appeler Dispose sur tous les objets membres qui le nécessitent.


Les objets courants qui ont besoin d'être utilisés sont les suivants : Les fichiers, les connexions aux bases de données, les objets graphiques tels que le stylo et le pinceau.


Parfois, il est également utilisé lorsque vous souhaitez que deux opérations se produisent simultanément. Par exemple, si vous voulez écrire une déclaration de journal lorsqu'un bloc de code est entré et lorsqu'il sort, vous pouvez écrire une classe de journal que vous pouvez utiliser comme ceci :

using( Log log = new Log("Doing stuff") )
{
    // Stuff
}

Le constructeur de la classe Log pourrait écrire le message, et la méthode Dispose pourrait également l'écrire. Implémentez le finalisateur (~Log) pour vérifier que la méthode Dispose n'est pas appelée afin de s'assurer que l'"utilisation" est conservée autour du "nouveau Log".

91voto

Otávio Décio Points 44200

Lorsque le SomeType La classe met en œuvre IDisposable .

13voto

bdukes Points 54833

Utilisez using lorsque le type implémente IDisposable à moins que vous ne vouliez l'envelopper dans une try / catch de toute façon, alors vous pourriez tout aussi bien (selon l'aspect que vous préférez) utiliser un bloc finally bloc.

12voto

Joel Coehoorn Points 190579

Je vois beaucoup d'autres réponses indiquées quand vous debe ont un using déclaration. Je voudrais aborder la question de savoir à quel moment précis no ont un using déclaration :

Si vous avez besoin d'utiliser votre objet en dehors de la portée de la fonction courante, n'ayez pas de using bloc. Un bon exemple est une méthode d'usine qui renvoie une connexion à une base de données ou une méthode qui doit renvoyer un datareader. Dans ces deux cas, si vous créez votre objet avec un bloc de type using il serait éliminé avant le retour de la méthode, et ne serait donc pas utilisable en dehors de la méthode.

Maintenant, tu veux toujours être sûr que ces objets sont éliminés, donc vous pourriez toujours vouloir une using quelque part. Mais ne l'incluez pas dans la méthode où l'objet est réellement créé. Au lieu de cela, vous pouvez envelopper l'appel de fonction lui-même dans une instruction de type using déclaration.

4voto

mbeckish Points 6180

Lorsque SomeType implémente IDisposable.

C'est un indice pour vous, le développeur, que SomeType utilise des ressources non gérées qui doivent être nettoyées.

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