c# documentation - Quand et pourquoi scelleriez-vous un cours?




generator see (4)

En C # et C ++ / CLI, le mot clé sealed (ou NotInheritable in VB) est utilisé pour protéger une classe de tout risque d'héritage (la classe ne sera pas héritable). Je sais que l'une des caractéristiques de la programmation orientée objet est l'héritage et je pense que l'utilisation de la fonction sealed va à l'encontre de cette fonctionnalité, elle arrête l'héritage. Y at-il un exemple qui montre l'avantage de sealed et quand il est important de l'utiliser?


Answers

Je pense que ce post a un bon point, le cas spécifique était lorsque vous essayez de lancer une classe non scellée à une interface aléatoire, le compilateur ne renvoie pas d'erreur; mais lorsqu'il est utilisé, le compilateur renvoie une erreur qu'il ne peut pas convertir. La classe scellée apporte une sécurité d'accès au code supplémentaire.
https://www.codeproject.com/Articles/239939/Csharp-Tweaks-Why-to-use-the-sealed-keyword-on-cla


Un additif à l'excellente réponse de Baboon:

3) Si une classe n'est pas conçue pour l'héritage, les sous-classes peuvent casser les invariants de classe . Cela s'applique uniquement si vous créez une API publique, bien sûr, mais en règle générale, je scelle toutes les classes qui ne sont pas explicitement conçues pour être sous-classées.

Sur une note connexe, applicable uniquement aux classes non scellées: toute méthode créée virtual est un point d'extension, ou du moins semble être un point d'extension. Déclarer des méthodes virtual devrait également être une décision consciente. (En C # c'est une décision consciente, en Java ce n'est pas le cas.)

EDIT : Quelques liens pertinents:

Notez également que Kotlin scelle les classes par défaut; son mot-clé open est l'opposé de la final de Java ou du sealed de C # . (Pour être sûr, il n'y a pas d'accord universel que c'est une bonne chose .)


1) Sur une classe qui implémente des fonctionnalités de sécurité, de sorte que l'objet d'origine ne puisse pas être "usurpé".

2) Plus généralement, j'ai récemment échangé avec une personne chez Microsoft, qui m'a dit qu'ils essayaient de limiter l'héritage aux endroits où cela avait vraiment du sens, parce que cela devenait coûteux en termes de performances s'ils n'étaient pas traités.
Le mot clé sealed indique au CLR qu'il n'y a pas de classe plus bas pour rechercher des méthodes, ce qui accélère les choses.

Dans la plupart des outils d'amélioration des performances sur le marché de nos jours, vous trouverez une case à cocher qui permettra de sceller toutes vos classes qui ne sont pas héritées.
Attention toutefois, car si vous souhaitez autoriser les plugins ou la découverte d'assembly via MEF, vous rencontrerez des problèmes.


Juste pour ajouter sur les réponses ci-dessus:

Si vous ne remplacez pas Equals, le comportement par défaut est que les références des objets sont comparées. La même chose s'applique à hashcode - l'implmentation par défaut est généralement basée sur une adresse mémoire de la référence. Parce que vous avez remplacé Equals, cela signifie que le comportement correct est de comparer tout ce que vous avez implémenté sur Equals et non les références, donc vous devriez faire la même chose pour le hashcode.

Les clients de votre classe s'attendront à ce que le hashcode ait une logique similaire à la méthode equals, par exemple les méthodes linq qui utilisent un IEqualityComparer comparent d'abord les hashcodes et seulement si elles sont égales elles compareront la méthode Equals () qui pourrait être plus chère pour exécuter, si nous n'avons pas implémenté le hashcode, l'objet égal aura probablement des hashcodes différents (parce qu'ils ont une adresse mémoire différente) et sera déterminé à tort comme non égal (Equals () ne frappera même pas).

De plus, excepté le problème que vous pourriez ne pas trouver votre objet si vous l'avez utilisé dans un dictionnaire (parce qu'il a été inséré par un hashcode et quand vous le cherchez le hashcode par défaut sera probablement différent et encore l'égal () ne sera même pas appelé, comme Marc Gravell l'explique dans sa réponse, vous introduisez également une violation du dictionnaire ou du concept hashset qui ne devrait pas permettre des clés identiques - vous avez déjà déclaré que ces objets sont essentiellement les mêmes lorsque vous surclastiez Equals ne pas vouloir les deux comme des clés différentes sur une structure de données supposée avoir une clé unique, mais comme ils ont un hashcode différent, la même clé sera insérée en tant que clé différente.







c# .net oop c++-cli