est-il raisonnable de faire une règle contre des appels explicitement Y a-t-il des cas où un Dispose () code> sur un objet code> Idisposable code>? P>
à l'aide de l'instruction code> ne peut pas assurer correctement un objet code> iDisposable code> est nettoyé? P>
6 Réponses :
Dans certains cas, il n'est tout simplement pas possible d'éviter un appel explicite à Disposer code> et maintenir toujours une sémantique appropriée. Par exemple, envisagez des objets code> Idisposables > d'objets qui ont un champ également de type
Idisposable code>. Ils doivent nous appeler un appel explicite à
Dispose code> pour disposer le champ
class Container : IDisposable {
private readonly IDisposable _field;
public void Dipose() {
// Don't want a using here.
_field.Dispose();
}
}
Eh bien, vous pouvez toujours utiliser un bloc d'utilisation pour déclencher la disposition ... mais ce serait bizarre car cela ne correspondrait pas à toute la durée de vie de l'objet, juste sa mort. Le en utilisant l'expression de contrôle code> n'a pas à créer l'objet, il suffit d'attribuer une variable.
@Benvoigt oui vous pourrait i> utiliser une utilisation. Ce serait un peu de surkillé cependant; 0
Si le coût de la création d'instances d'un type jetable est élevé (par exemple, un type qui encapsule une connexion distante), vous pouvez souhaiter réutiliser des instances pour amortir le coût. Dans ce cas, en utilisant code> ne sera pas utile et vous devrez appeler
Disposer code> à un moment donné. p>
Je voterais contre une telle règle, que si vous avez un objet que vous souhaitez utiliser plusieurs fois sur plusieurs appels de fonction, une instruction utilisant la disposition de cet objet, la prochaine fois que vous souhaitez l'utiliser, vous devez Réinitialiser ... P>
est-il raisonnable de faire une règle contre des appels explicitement
Dispose () code> sur un objet code> Idisposable code>? P> blockQuote>
Non. P>
Y a-t-il des cas où un
à l'aide de l'instruction code> ne peut pas assurer correctement un objet code> iDisposable code> est nettoyé? P> blockQuote>
Il y a certainement des cas où il n'a aucun sens d'utiliser
en utilisant code> pour disposer d'un objet pour vous. Par exemple, tous les cas où la durée de vie souhaitée de l'objet n'est pas liée par une activation particulière d'un procédé contenant un
à l'aide de la déclaration code> " p>
Considérez par exemple un objet jetable qui «prend en charge la gestion» d'un autre objet jetable. L'objet "externe" peut bien être disposé par un bloc
à l'aide du bloc code>, mais comment est l'objet "intérieur", probablement stocké dans un champ privé de l'objet extérieur, à disposer sans appel explicitement à < code> Dispose () code>? p>
Une bonne réponse propre! Je suppose que la question a poussé de mon amour à la retraite pour C ++ et sa syntaxe propre pour exprimer Raii.
@Nickstrupat: par "Syntaxe propre" Vous voulez dire "Le caractère } code> provoque l'exécution de". Ce n'est pas une syntaxe "propre", il s'agit d'une syntaxe dangereusement trompeuse. Le caractère qui démarquait une portée lexicale ne doit pas être associé à code exécutable i>; Le fait qu'il soit en C ++ est l'un des défauts de conception de C ++. Il continue d'être mystérieux pour moi pourquoi quiconque pense que c'est une bonne idée; Si mon code de nettoyage de ressources est important, je veux que ce soit explicite i> dans le code afin que je puisse lire i>, comprendre i> et debug i> ça. Si c'est important, ne le cachez pas.
@ERIFLIPPERT - Pour jouer à Devil's Advocate, le } code> qui ferme un
en utilisant le bloc code> en C # provoque sans doute exécuter le code à exécuter. Sensez-vous que la syntaxe "dangereusement trompeuse" est "ou est la présence" en utilisant "au début du bloc suffisant pour l'excuser?
@KVB: "Utiliser" (ou "ou" foreach "ou" verrou ") appelle clairement que le bloc qui suit a une sémantique spéciale.
@ERIC - et en C #, il est nécessaire d'utiliser des blocs spécialement marqués car leur comportement est inhabituel. Mais en C ++, la pile Les valeurs allouées sont toujours détruites à la fin de leur portée, non? Je ne suis pas complètement convaincu que laisser la destruction implicite nécessairement problématique, mais je n'ai pas touché C ++ depuis des années, donc je vais reporter à votre jugement.
@KVB: De plus, "Dispose" La sémantique est pour Poluress i> - pour que une ressource rare soit nettoyée tôt. La sémantique Raii est fréquemment utilisée pour garantir exactitude i>. Je dis que si un programme repose sur une fonction de fonction particulière à son correctionness i>, cet appel de fonction devrait réellement apparaître quelque part dans le programme.
@ERICLIPPERT, je pense que cela n'est pas inhabituel que le dispositif est utilisé pour l'exactitude. Par exemple, appeler dipose () code> sur un "code> streamwriter code> flushèse sa mémoire tampon. Ne pas l'appeler (et s'appuyer sur la finalisation) signifie que le tampon n'est jamais rincé, le contenu du fichier est donc incorrect.
A à l'aide de code> instruction (qui est réellement sténographique pour essayer / enfin avec
Dispose code> appelé dans le bloc enfin) est pour les scénarios où vous acquérez une ressource, utilisez Ensuite, jetez-le dans une même méthode. Si vous n'avez pas d'utilisation aussi linéaire de la ressource (par exemple, son utilisation est divisée sur des méthodes), vous devrez appeler
Disposer code>. P>
Une hypothèse naturelle est que vous pouvez toujours appeler Cette hypothèse naturelle n'est pas Toujours une hypothèse correcte. P> Un exemple est avec wcf Proxies des clients. . p> La bonne façon de gérer la durée de vie du proxy est la suivante: p> commutation sur le vous pouvez argumenter ( comme nous le faisons tous em>) qu'il s'agit d'un aspect de conception imparfait de WCF, Mais la réalité de la programmation est que nous devons parfois modifier notre style pour accueillir les cadres que nous utilisons. Voici un exemple où une règle de couverture contre explicite Disposer code> sur un objet, et cela nettoyera les ressources de l'objet, quel que soit l'état de l'objet.
en utilisant Code> La syntaxe aboutira à un code dangereux: p>
Dispose code> ne peut pas s'appliquer, même lorsque la durée de vie de l'objet est contenue dans un appel de fonction. P> P>
Autant que j'aime laisser le collectionneur des ordures gérer ma mémoire pour moi, je n'ai aucune réserve contre appel à disposer () si j'ai une raison de le faire.
@Samiam: Le point d'appeler Dispose consiste à libérer une ressource que le gestionnaire de mémoire ne vous libère pas pour vous i>. Dispose explicitement sur la gestion des ressources non mémoire i>, alors n'apporte pas le gestionnaire de mémoire du tout.