¿Por qué sellar una clase?

Me gustaría escuchar cuál es la motivación detrás de la mayor parte de las clases selladas en .Net Framework. ¿Cuál es el beneficio de sellar una clase? No puedo entender cómo no permitir que la herencia sea útil y, probablemente, no la única que combate estas clases.

Entonces, ¿por qué el marco está diseñado de esta manera y no sería un cambio inquebrantable para desbloquear todo? Debe haber otra razón, pero solo ser malvado?

  • A veces las clases son demasiado valiosas y no están diseñadas para ser heredadas.
  • Runtime / Reflection puede hacer suposiciones de herencia sobre clases selladas al buscar tipos. Un gran ejemplo de esto es: se recomienda que los atributos estén sellados para la velocidad de tiempo de ejecución de búsqueda. type.GetCustomAttributes (typeof (MyAttribute)) funcionará significativamente más rápido si MyAttribute está sellado.

El artículo de MSDN para este tema es Límite de extensibilidad mediante clases de sellado .

Las clases deben estar diseñadas para herencia o prohibirlas. Hay un costo para diseñar para la herencia:

  • Puede precisar su implementación (debe declarar qué métodos van a llamar a qué otros métodos, en caso de que un usuario anule uno pero no el otro)
  • Revela su implementación en lugar de solo los efectos
  • Significa que tienes que pensar en más posibilidades al diseñar
  • Cosas como Equals son difíciles de diseñar en un árbol de herencia
  • Requiere más documentación
  • Un tipo inmutable que está subclasificado puede volverse mutable (ick)

El elemento 17 de Java efectivo entra en más detalles sobre esto, independientemente del hecho de que esté escrito en el contexto de Java, el consejo también se aplica a .NET.

Personalmente, desearía que las clases estuvieran selladas por defecto en .NET.

Parece que las directrices oficiales de Microsoft sobre el sellado han evolucionado desde que se hizo esta pregunta hace 9 años, y pasaron de una filosofía de aceptación (sello por defecto) a la exclusión voluntaria (no sellar por defecto):

X NO SELECCIONE las clases sin tener una buena razón para hacerlo.

Sellar una clase porque no se puede pensar en un escenario de extensibilidad no es una buena razón. A los usuarios de Framework les gusta heredar de las clases por varias razones no obvias, como agregar miembros de conveniencia. Consulte Clases no selladas para ver ejemplos de razones no obvias por las que los usuarios desean heredar de un tipo.

Las buenas razones para sellar una clase incluyen las siguientes:

  • La clase es una clase estática. Vea diseño de clase estática.
  • La clase almacena secretos sensibles a la seguridad en miembros protegidos heredados.
  • La clase hereda muchos miembros virtuales y el costo de sellarlos individualmente superaría los beneficios de dejar la clase sin sellar.
  • La clase es un atributo que requiere una búsqueda de tiempo de ejecución muy rápida. Los atributos sellados tienen niveles de rendimiento ligeramente más altos que los no sellados. Ver atributos.

X NO declarar miembros protegidos o virtuales en tipos sellados.

Por definición, los tipos sellados no pueden ser heredados de. Esto significa que los miembros protegidos de los tipos sellados no se pueden llamar, y los métodos virtuales en los tipos sellados no se pueden anular.

✓ CONSIDERE los miembros de sellado que anula. Los problemas que pueden surgir al introducir miembros virtuales (discutidos en Miembros virtuales) también se aplican a las modificaciones, aunque en menor grado. El sellado de una anulación lo protege de estos problemas a partir de ese punto en la jerarquía de herencia.

De hecho, si busca en la base de código ASP.Net Core , solo encontrará aproximadamente 30 ocurrencias de sealed class , la mayoría de las cuales son atributos y clases de prueba.

Creo que la conservación de la inmutabilidad es un buen argumento a favor del sellamiento.

Encontré esta oración en la documentación de msdn: “Las clases selladas se usan principalmente para evitar la derivación. Debido a que nunca se pueden usar como una clase base, algunas optimizaciones en tiempo de ejecución pueden hacer que llamar a miembros de clase sellados sea un poco más rápido”.

No sé si el rendimiento es la única ventaja de las clases selladas y personalmente también me gustaría saber otras razones …

El rendimiento es un factor importante, por ejemplo, la clase de cadena en Java es final (< - sellado) y la razón de esto es solo el rendimiento. Creo que otro punto importante es evitar el problema de clase base frágil que se describe en detalle aquí: http://blogs.msdn.com/ericlippert/archive/2004/01/07/virtual-methods-and-brittle-base-classes. aspx

Si proporciona un marco, es importante para los proyectos heredados de mantenimiento y para actualizar su marco para evitar el problema de la clase base frágil

Sealed se usa para prevenir el “problema de clase base frágil”. Encontré un buen artículo en MSDN que lo explica.

El sellado le permite obtener algunas ganancias de rendimiento menores. Esto es menos cierto en el mundo de los JIT y la pesimista perezosa que en el mundo de, digamos C ++, pero dado que .NET no es tan bueno como la pesimismo ya que los comstackdores de Java se deben principalmente a diferentes filosofías de diseño, sigue siendo útil. Le dice al comstackdor que puede llamar directamente a cualquier método virtual en lugar de llamarlos indirectamente a través del vtable.

También es importante cuando quieres un “mundo cerrado” para cosas como la comparación de igualdad. Normalmente, una vez que defino un método virtual, casi me manchan por definir una noción de comparación de igualdad que realmente implemente la idea. Por otro lado, podría definirlo para una subclase particular de la clase con el método virtual. Sellar esa clase asegura que la igualdad realmente se mantenga.

Sellar una clase facilita la gestión de los recursos desechables.

Para determinar si se debe sellar una clase, método o propiedad, generalmente debe considerar los dos puntos siguientes:

• Los beneficios potenciales que las clases derivadas podrían obtener a través de la capacidad de personalizar su clase.

• El potencial de que las clases que derivan puedan modificar sus clases de tal manera que ya no funcionarían correctamente o como se esperaba.

Una consideración adicional es que las clases selladas no se pueden anular en las pruebas de su unidad. De la documentación de Microsoft :

Las clases selladas o los métodos estáticos no se pueden anular porque los tipos de código auxiliar se basan en el envío de métodos virtuales. Para tales casos, use los tipos de calzas como se describe en Uso de Calzas para aislar su aplicación de otros conjuntos para pruebas unitarias