Dans un modèle IDisposable devrait une classe de base permettent aux classes dérivées de partager son drapeau disposé?

StackOverflow https://stackoverflow.com/questions/1079752

  •  21-08-2019
  •  | 
  •  

Question

Je travaille actuellement sur la fixation d'un c # codebase qui ne dispose pas d'un bon modèle d'utilisation Dispose.

Il est un grand codebase, il est une base de code exigeant des ressources et il utilise beaucoup de bibliothèques C ++ non géré sur mesure au niveau bas.

J'ai une bonne compréhension du motif de Éliminez. J'ai passé un certain temps à comprendre ce que je crois être l'article standard de l'or sur la question: l'article de Joe Duffy Éliminez

Dans une tentative de minimiser la duplication de code, nous avons examiné certaines classes d'aide de Dispose, et donc ma question:

Si une classe de base implémente un modèle standard Dispose devrait lui permettre son drapeau disposé à partager par exemple. marqué comme protégé?

Pour clarifier, je veux dire devrait y avoir qu'un seul état booléen dans une hiérarchie d'héritage qui définit si une instance d'objet a été supprimé ou doit y avoir un booléen privé à chaque étape de l'échelle de succession?

Les exemples de MSDN et au lien ci-dessus fixé un drapeau à chaque niveau, mais jamais expliquer le raisonnement derrière elle. Je suis dans deux esprits sur la question, quelles sont vos pensées et vos raisons?

Était-ce utile?

La solution

Je dirais pas qu'il ne devrait pas partager le drapeau. Le partage du drapeau crée des opportunités pour une meilleure encapsulation échec qui pourrait empêcher.

Par exemple, considérons le scénario où vous avez une propriété Disposé sur la base readonly plus classe. Le champ de support est uniquement défini sur vrai dans la méthode Dispose (élimination) de la classe de base. Cela signifie que la propriété ne peut jamais Disposés retourner vrai si la classe de base Dispose est appelée (sauf réflexion mal bien sûr). Cela permet à la classe de base pour fournir un contrat exécutoire.

Considérons maintenant le contraire, où il y a un poseur protégé. Toute classe peut maintenant définir arbitrairement la propriété Disposé true sans disposer quoi que ce soit. Cela crée une opportunité pour revenir Éliminez vrai quand rien est disposé.

Je choisirais la première option, car elle fournit le contrat le plus exécutoire.

Autres conseils

Je recommande d'avoir une propriété sur la classe Disposé de base avec un getter public et un setter protégé.

Dans le cas où vous avez des méthodes qui devraient faire quelque chose de différent lorsque la classe a été disposé, par exemple lancer une exception, je créerais un protégé que getter propriété pour la classe de base qui lit le champ privé sur la classe de base. De cette façon, vous permet tout de savoir si Héritier il est capable d'effectuer une opération.

Alors, pour savoir si une classe a déjà été disposé dans sa propre méthode dispose (par exemple: pour éviter de dégager des ressources deux fois), je pense que d'avoir un drapeau privé est mieux pour la clarté et l'entretien

.

En plus de la réponse de JaredPar, j'ajouter qu'il est pas toujours nécessaire pour qu'il y ait un drapeau _disposed. Très souvent, les autres domaines « liés aux ressources » de l'objet fournissent naturellement une façon de représenter l'état disposé.

Par exemple, un objet COM externe qui doit être avant qu'il ne soit Shutdown mis au rebut serait représenté par une référence à l'objet COM, et ainsi de la partie pertinente serait Dispose:

if (_comObject != null)
{
    _comObject.Shutdown();
    _comObject = null;
}

Cela peut être exécuté en toute sécurité plusieurs fois sans faire appel à plus d'une fois NullReferenceException, comme cela est nécessaire. D'autres méthodes qui tentent d'utiliser _comObject après recevront un ObjectDisposedException <=>, ou idéalement ces méthodes vérifieraient le champ _comObject et lancer <=>.

Je trouve cela est plus souvent vrai que pas - ayant souvent mis en œuvre IDisposable, je ne me souviens jamais avoir besoin d'un champ distinct <=>. Présentation on augmenterait les degrés de liberté (augmenter le nombre de façons pour moi de le visser vers le haut).

Alors il est peu probable d'être utile que pour les classes dérivées, même si elle était une idée sûre (ce qui ne l'est pas, comme JaredPar explique).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top