9
votes

Est-il raisonnable d'éviter des appels explicites pour disposer ()?

est-il raisonnable de faire une règle contre des appels explicitement Dispose () sur un objet Idisposable ?

Y a-t-il des cas où un à l'aide de l'instruction ne peut pas assurer correctement un objet iDisposable est nettoyé?


2 commentaires

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 . Dispose explicitement sur la gestion des ressources non mémoire , alors n'apporte pas le gestionnaire de mémoire du tout.


6 Réponses :


5
votes

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();
  }
}


2 commentaires

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 n'a pas à créer l'objet, il suffit d'attribuer une variable.


@Benvoigt oui vous pourrait utiliser une utilisation. Ce serait un peu de surkillé cependant; 0



1
votes

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 ne sera pas utile et vous devrez appeler Disposer à un moment donné.


0 commentaires

1
votes

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 ...


0 commentaires

11
votes

est-il raisonnable de faire une règle contre des appels explicitement Dispose () sur un objet Idisposable ?

Non.

Y a-t-il des cas où un à l'aide de l'instruction ne peut pas assurer correctement un objet iDisposable est nettoyé?

Il y a certainement des cas où il n'a aucun sens d'utiliser en utilisant 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 "

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 , mais comment est l'objet "intérieur", probablement stocké dans un champ privé de l'objet extérieur, à disposer sans appel explicitement à < code> Dispose () ?


7 commentaires

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 } 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 ; 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 dans le code afin que je puisse lire , comprendre et debug ça. Si c'est important, ne le cachez pas.


@ERIFLIPPERT - Pour jouer à Devil's Advocate, le } qui ferme un en utilisant le bloc 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 - pour que une ressource rare soit nettoyée tôt. La sémantique Raii est fréquemment utilisée pour garantir exactitude . Je dis que si un programme repose sur une fonction de fonction particulière à son correctionness , 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 () sur un "code> streamwriter 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.



2
votes

A à l'aide de instruction (qui est réellement sténographique pour essayer / enfin avec Dispose 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 .


0 commentaires

3
votes

Une hypothèse naturelle est que vous pouvez toujours appeler Disposer sur un objet, et cela nettoyera les ressources de l'objet, quel que soit l'état de l'objet.

Cette hypothèse naturelle n'est pas Toujours une hypothèse correcte.

Un exemple est avec wcf Proxies des clients. .

La bonne façon de gérer la durée de vie du proxy est la suivante: xxx

commutation sur le en utilisant La syntaxe aboutira à un code dangereux: xxx

vous pouvez argumenter ( comme nous le faisons tous ) 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 Dispose ne peut pas s'appliquer, même lorsque la durée de vie de l'objet est contenue dans un appel de fonction.


0 commentaires