Pourquoi sceller une classe?

J’aimerais savoir quelle est la motivation derrière le gros des classes scellées dans le framework .Net. Quel est l’avantage de sceller une classe? Je ne peux pas comprendre comment ne pas permettre l’inheritance peut être utile et probablement pas le seul à combattre ces classes.

Alors, pourquoi le cadre est-il conçu de cette manière et ne serait-ce pas un changement irrésistible pour tout ouvrir? Il doit y avoir une autre raison mais être juste le mal?

  • Parfois, les cours sont trop précieux et ne sont pas conçus pour être hérités.
  • Runtime / Reflection peut créer des hypothèses d’inheritance sur les classes scellées lors de la recherche de types. Un bon exemple est le suivant: il est recommandé que les atsortingbuts soient scellés pour la vitesse d’exécution de la recherche. type.GetCustomAtsortingbutes (typeof (MyAtsortingbute)) fonctionnera beaucoup plus rapidement si MyAtsortingbute est scellé.

L’article MSDN pour cette rubrique limite l’extensibilité par les classes de scellement .

Les classes doivent être conçues pour l’inheritance ou l’interdire. Il y a un coût à concevoir pour l’inheritance:

  • Il peut définir votre implémentation (vous devez déclarer quelles méthodes vont appeler quelles autres méthodes, au cas où un utilisateur écrase l’une mais pas l’autre)
  • Il révèle votre implémentation plutôt que les effets
  • Cela signifie que vous devez penser à plus de possibilités lors de la conception
  • Des choses comme Equals sont difficiles à concevoir dans un arbre d’inheritance
  • Cela nécessite plus de documentation
  • Un type immuable qui est sous-classé peut devenir mutable (ick)

Le point 17 de Effective Java va plus en détail à ce sujet – indépendamment du fait qu’il soit écrit dans le contexte de Java, les conseils s’appliquent également à .NET.

Personnellement, je souhaite que les cours soient scellés par défaut dans .NET.

Il semble que les directives officielles de Microsoft sur le scellement aient évolué depuis que cette question a été posée, il y a environ 9 ans, et elles sont passées de la philosophie opt-in (sceller par défaut) à la désactivation (ne pas sceller par défaut):

X NE PAS sceller les classes sans avoir une bonne raison de le faire.

Sceller une classe parce que vous ne pouvez pas penser à un scénario d’extensibilité n’est pas une bonne raison. Les utilisateurs du framework aiment hériter des classes pour diverses raisons non évidentes, comme l’ajout de membres de commodité. Voir Classes non scellées pour des exemples de raisons non évidentes que les utilisateurs souhaitent hériter d’un type.

Les bonnes raisons pour sceller une classe sont les suivantes:

  • La classe est une classe statique. Voir la conception de la classe statique.
  • La classe stocke les secrets sensibles à la sécurité dans les membres protégés hérités.
  • La classe hérite de nombreux membres virtuels et le coût de leur scellement individuel l’emporterait sur les avantages de ne pas sceller la classe.
  • La classe est un atsortingbut qui nécessite une recherche d’exécution très rapide. Les atsortingbuts scellés ont des performances légèrement supérieures à celles des atsortingbuts non scellés. Voir Atsortingbuts.

X NE déclarez PAS de membres protégés ou virtuels sur des types scellés.

Par définition, les types scellés ne peuvent pas être hérités. Cela signifie que les membres protégés sur les types scellés ne peuvent pas être appelés et que les méthodes virtuelles sur les types scellés ne peuvent pas être remplacées.

✓ CONSIDERER les membres d’étanchéité que vous remplacez. Les problèmes pouvant résulter de l’introduction de membres virtuels (abordés dans la section Membres virtuels) s’appliquent également aux dérogations, mais dans une moindre mesure. Sceller une substitution vous protège de ces problèmes à partir de ce point dans la hiérarchie d’inheritance.

En effet, si vous effectuez une recherche dans le code ASP.Net Core , vous ne trouverez que 30 occurrences de sealed class , dont la plupart sont des atsortingbuts et des classes de test.

Je pense que la conservation de l’immuabilité est un bon argument en faveur du scellement.

J’ai trouvé cette phrase dans la documentation msdn: “Les classes scellées sont principalement utilisées pour empêcher la dérivation. Comme elles ne peuvent jamais être utilisées comme classe de base, certaines optimisations d’exécution peuvent accélérer l’appel des membres de classe scellés.”

Je ne sais pas si la performance est le seul avantage des classes scellées et personnellement, j’aimerais aussi connaître d’autres raisons …

Les performances sont un facteur important, par exemple, la classe de chaînes dans Java est finale (<- scellée) et la raison en est uniquement les performances. Je pense qu'un autre point important est d'éviter le problème de la classe de base fragile décrit en détail ici: http://blogs.msdn.com/ericlippert/archive/2004/01/07/virtual-methods-and-brittle-base-classes. aspx

Si vous fournissez un framework, il est important pour les projets hérités de maintenabilité et pour mettre à niveau votre framework afin d’éviter le problème de la classe de base fragile

Sealed est utilisé pour empêcher le “problème de la classe de base fragile”. J’ai trouvé un bon article dans MSDN qui explique cela.

Le scellement vous permet de réaliser des gains de performance mineurs. Ceci est moins vrai dans le monde des JIT et de la pessimisation paresseuse que dans le monde, disons en C ++, mais comme .NET n’est pas aussi bon que la pessimisation car les compilateurs Java sont principalement dus à des philosophies de conception différentes. Il indique au compilateur qu’il peut appeler directement toutes les méthodes virtuelles plutôt que de les appeler indirectement via la vtable.

Il est également important lorsque vous voulez un monde fermé pour des choses comme la comparaison d’égalité. Normalement, une fois que je définis une méthode virtuelle, je suis plutôt intéressé par la définition d’une notion de comparaison d’égalité qui implémente vraiment l’idée. D’autre part, je pourrais être en mesure de le définir pour une sous-classe particulière de la classe avec la méthode virtuelle. Sceller cette classe garantit que l’égalité tient vraiment.

Sceller une classe facilite la gestion des ressources disponibles.

Pour déterminer si vous souhaitez sceller une classe, une méthode ou une propriété, vous devez généralement considérer les deux points suivants:

• Les avantages potentiels que les classes dérivant peuvent gagner grâce à la possibilité de personnaliser votre classe.

• La possibilité que des classes dérivées puissent modifier vos classes de manière à ce qu’elles ne fonctionnent plus correctement ou comme prévu.

Une autre considération est que les classes scellées ne peuvent pas être écrasées dans vos tests unitaires. De la documentation de Microsoft :

Les classes scellées ou les méthodes statiques ne peuvent pas être écrasées, car les types de stub reposent sur la dissortingbution de méthodes virtuelles. Dans ce cas, utilisez les types de cales décrits dans la section Utilisation de cales pour isoler votre application des autres assemblages pour les tests unitaires.