My answer: poor design choice. ;-)
This is an interesting debate focused on syntax impact. The core of the argument, in my view, is that a design decision led to sealed static classes. A focus on transparency of the static class's names appearing at the top level instead of hiding ('confusing') behind child names? One can image a language implementation that could access the base or the child directly, confusing.
A pseudo example, assuming static inheritance was defined in some way.
public static class MyStaticBase
{
SomeType AttributeBase;
}
public static class MyStaticChild : MyStaticBase
{
SomeType AttributeChild;
}
would lead to:
// ...
DoSomethingTo(MyStaticBase.AttributeBase);
// ...
which could (would?) impact the same storage as
// ...
DoSomethingTo(MyStaticChild.AttributeBase);
// ...
Very confusing!
But wait! How would the compiler deal with MyStaticBase and MyStaticChild having the same signature defined in both? If the child overrides than my above example would NOT change the same storage, maybe? This leads to even more confusion.
I believe there is a strong informational space justification for limited static inheritance. More on the limits shortly. This pseudocode shows the value:
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(){/*...*/};
}
Then you get:
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...
}
Usage looks like:
// ...
MyStaticChild.Load(FileNamePath);
MyStaticChild.Save(FileNamePath);
doSomeThing(MyStaticChild.Payload.Attribute);
doSomething(MyStaticChild.AttributeBase);
doSomeThing(MyStaticChild.AttributeChild);
// ...
The person creating the static child does not need to think about the serialization process as long as they understand any limitations that might be placed on the platform's or environment's serialization engine.
Statics (singletons and other forms of 'globals') often come up around configuration storage. Static inheritance would allow this sort of responsibility allocation to be cleanly represented in the syntax to match a hierarchy of configurations. Though, as I showed, there is plenty of potential for massive ambiguity if basic static inheritance concepts are implemented.
I believe the right design choice would be to allow static inheritance with specific limitations:
- No override of anything. The child cannot replace the base
attributes, fields, or methods,... Overloading should be ok, as
long as there is a difference in signature allowing the compiler to
sort out child vs base.
- Only allow generic static bases, you cannot inherit from a
non-generic static base.
You could still change the same store via a generic reference MyStaticBase<ChildPayload>.SomeBaseField
. But you would be discouraged since the generic type would have to be specified. While the child reference would be cleaner: MyStaticChild.SomeBaseField
.
I am not a compiler writer so I am not sure if I am missing something about the difficulties of implementing these limitations in a compiler. That said, I am a strong believer that there is an informational space need for limited static inheritance and the basic answer is that you can't because of a poor (or over simple) design choice.