2009-02-13 5 views
4

Je lisais une autre réponse. Et ça m'a fait me demander, quand est-ce qu'on a besoin d'appeler explicitement Dispose si j'utilise les instructions using?Quand avez-vous besoin d'appeler IDisposable, si vous utilisez des instructions `using`?

EDIT:

Juste pour me justifier d'être un savoir rien au total, la raison pour laquelle j'ai demandé parce que quelqu'un était sur un autre thread a dit quelque chose ce qui implique qu'il y avait une bonne raison d'avoir à appeler Dispose manuellement ... Donc, Je me suis dit, pourquoi ne pas demander à ce sujet?

+0

J'aime ce genre de questions apparemment simples sur StackOverflow. Je suis toujours surpris de la quantité d'informations que vous pouvez obtenir sur une telle question. Je ne connaissais pas le problème des initialiseurs d'objets ... –

+0

SO est définitivement un site génial. Je me plais beaucoup ici. –

Répondre

20

Ce n'est pas le cas. La déclaration using le fait pour vous.


Selon MSDN, cet exemple de code:

using (Font font1 = new Font("Arial", 10.0f)) 
{ 
    byte charset = font1.GdiCharSet; 
} 

est dilatée, lors de la compilation, le code suivant (notez les accolades supplémentaires pour créer la portée limitée de l'objet):

{ 
    Font font1 = new Font("Arial", 10.0f); 
    try 
    { 
    byte charset = font1.GdiCharSet; 
    } 
    finally 
    { 
    if (font1 != null) 
     ((IDisposable)font1).Dispose(); 
    } 
} 

note: Comme @timvw mentioned, si vous chaînez des méthodes ou utilisez des initialiseurs d'objet dans l'instruction using elle-même et qu'une exception est levée, l'objet ne sera pas éliminé. Ce qui est logique si vous regardez à quoi il va être étendu. Par exemple:

using(var cat = new Cat().AsDog()) 
{ 
    // Pretend a cat is a dog 
} 

se développe pour

{ 
    var cat = new Cat().AsDog(); // Throws 
    try 
    { 
    // Never reached 
    } 
    finally 
    { 
    if (cat != null) 
     ((IDisposable)cat).Dispose(); 
    } 
}  

AsDog va évidemment lancer une exception, car un chat ne peut jamais être aussi impressionnant comme un chien. Le chat ne sera alors jamais éliminé. Bien sûr, certaines personnes peuvent prétendre que les chats ne devraient jamais être éliminés, mais c'est une autre discussion ...

De toute façon, assurez-vous que ce que vous faites using(here) est sûr et vous êtes prêt à partir. (Evidemment, si le constructeur échoue, l'objet ne sera pas créé pour commencer, donc pas besoin de disposer).

+1

+1. . . Je ne suis pas une personne de chat. . . –

+0

Comment est-ce génial que la publicité que je lis ceci est un beagle à la recherche d'un emploi sur Careers.stackexchange.com –

5

Jamais. Il appellera Dispose une fois que les instructions à l'intérieur des blocs auront fini d'être exécutées.

3

Le point entier de l'instruction using est que si votre objet implémente IDisposable, le dipose sera appelé à la fin du bloc de code. C'est pour ça qu'il est là, pour le faire automatiquement pour vous.

12

Normalement, vous ne le faites pas. C'est le point de l'instruction using. Il existe cependant une situation dans laquelle vous devez faire attention:

Si vous réaffectez la variable à une autre valeur, l'instruction using n'appellera que la méthode Dispose sur la valeur d'origine.

using (someValue = new DisposableObject()) 
{ 
    someValue = someOtherValue; 
} 

Le compilateur va même vous donner un Avertissement à ce sujet:

affectation Peut-être incorrecte au niveau local « someValue » qui est l'argument d'une instruction à l'aide ou d'un lock. L'appel ou le déverrouillage se fera sur la valeur d'origine du local.

+0

+1 pour mentionner le problème de réaffectation. –

+1

Je crois que cet avertissement est remplacé par une erreur dans C# 3.5: "erreur CS1656: Impossible d'assigner à 'someValue' parce qu'il s'agit d'une 'variable using'" – Dathan

3

En autant que je sache

using (var myDisposable = new MyDisposable()) 
{ 
    ... 
} 

est essentiellement traduit par le compilateur à

var myDisposable = new MyDisposable() 
try 
{ 
    ... 
} 
finally 
{ 
    myDisposable.Dispose(); 
} 
+1

Il entoure également le bloc entier entre accolades pour limiter la portée de myDisposable, et ajoute une vérification dans le bloc finally pour exécuter uniquement Dispose() sur les instances non nulles de myDisposable. – Dathan

Questions connexes