Mi respuesta: mala elección de diseño. ;-)
Este es un debate interesante centrado en el impacto de la sintaxis. El núcleo del argumento, en mi opinión, es que una decisión de diseño condujo a clases estáticas selladas. ¿Un enfoque en la transparencia de los nombres de la clase estática que aparecen en el nivel superior en lugar de esconderse ('confundir') detrás de los nombres secundarios? Uno puede imaginar una implementación de lenguaje que podría acceder a la base o al niño directamente, confuso.
Un pseudo ejemplo, suponiendo que la herencia estática se definió de alguna manera.
public static class MyStaticBase
{
SomeType AttributeBase;
}
public static class MyStaticChild : MyStaticBase
{
SomeType AttributeChild;
}
daría lugar a:
// ...
DoSomethingTo(MyStaticBase.AttributeBase);
// ...
que podría (afectaría) el mismo almacenamiento que
// ...
DoSomethingTo(MyStaticChild.AttributeBase);
// ...
¡Muy confuso!
¡Pero espera! ¿Cómo trataría el compilador con MyStaticBase y MyStaticChild con la misma firma definida en ambos? Si el niño anula que mi ejemplo anterior NO cambiaría el mismo almacenamiento, ¿tal vez? Esto lleva a una mayor confusión.
Creo que existe una fuerte justificación del espacio informativo para la herencia estática limitada. Más sobre los límites en breve. Este pseudocódigo muestra el valor:
public static class MyStaticBase<T>
{
public static T Payload;
public static void Load(StorageSpecs);
public static void Save(StorageSpecs);
public static SomeType AttributeBase
public static SomeType MethodBase(){/*...*/};
}
Entonces obtienes:
public static class MyStaticChild : MyStaticBase<MyChildPlayloadType>
{
public static SomeType AttributeChild;
public static SomeType SomeChildMethod(){/*...*/};
// No need to create the PlayLoad, Load(), and Save().
// You, 'should' be prevented from creating them, more on this in a sec...
}
El uso se parece a:
// ...
MyStaticChild.Load(FileNamePath);
MyStaticChild.Save(FileNamePath);
doSomeThing(MyStaticChild.Payload.Attribute);
doSomething(MyStaticChild.AttributeBase);
doSomeThing(MyStaticChild.AttributeChild);
// ...
La persona que crea el niño estático no necesita pensar en el proceso de serialización siempre y cuando comprenda las limitaciones que se pueden colocar en el motor de serialización de la plataforma o el entorno.
Las estadísticas (singletons y otras formas de 'globales') a menudo surgen en torno al almacenamiento de configuración. La herencia estática permitiría que este tipo de asignación de responsabilidad se representara limpiamente en la sintaxis para que coincida con una jerarquía de configuraciones. Sin embargo, como mostré, existe un gran potencial para una ambigüedad masiva si se implementan conceptos básicos de herencia estática.
Creo que la opción de diseño correcta sería permitir la herencia estática con limitaciones específicas:
- Sin anulación de nada. El elemento secundario no puede reemplazar los atributos, campos o métodos base, ... La sobrecarga debería estar bien, siempre que haya una diferencia en la firma que permita al compilador clasificar el elemento secundario frente a la base.
- Solo permita bases estáticas genéricas, no puede heredar de una base estática no genérica.
Aún puede cambiar la misma tienda a través de una referencia genérica MyStaticBase<ChildPayload>.SomeBaseField
. Pero se desanimaría ya que el tipo genérico tendría que especificarse. Si bien la referencia secundaria sería más limpia:MyStaticChild.SomeBaseField
.
No soy un escritor compilador, así que no estoy seguro de si me falta algo sobre las dificultades de implementar estas limitaciones en un compilador. Dicho esto, creo firmemente que existe una necesidad de espacio informativo para una herencia estática limitada y la respuesta básica es que no se puede debido a una elección de diseño pobre (o demasiado simple).