Мой ответ: неудачный выбор дизайна. ;-)
Это интересная дискуссия, посвященная влиянию синтаксиса. Суть аргумента, на мой взгляд, заключается в том, что проектное решение привело к запечатанным статическим классам. Акцент на прозрачности имен статических классов, появляющихся на верхнем уровне, вместо того, чтобы прятаться («сбивать с толку») за дочерними именами? Можно представить себе языковую реализацию, которая может напрямую обращаться к базе или к ребенку, что может сбить с толку.
Псевдо-пример, предполагающий статическое наследование, был определен некоторым образом.
public static class MyStaticBase
{
SomeType AttributeBase;
}
public static class MyStaticChild : MyStaticBase
{
SomeType AttributeChild;
}
приведет к:
// ...
DoSomethingTo(MyStaticBase.AttributeBase);
// ...
который может (будет?) влиять на то же хранилище, что и
// ...
DoSomethingTo(MyStaticChild.AttributeBase);
// ...
Очень запутанно!
Но ждать! Как компилятор будет иметь дело с MyStaticBase и MyStaticChild, имеющими одинаковую сигнатуру, определенную в обоих? Если ребенок переопределяет, чем мой приведенный выше пример, НЕ изменится то же хранилище, может быть? Это приводит к еще большему замешательству.
Я считаю, что существует сильное информационное пространство для ограниченного статического наследования. Подробнее о пределах в ближайшее время. Этот псевдокод показывает значение:
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(){/*...*/};
}
Тогда вы получите:
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...
}
Использование выглядит так:
// ...
MyStaticChild.Load(FileNamePath);
MyStaticChild.Save(FileNamePath);
doSomeThing(MyStaticChild.Payload.Attribute);
doSomething(MyStaticChild.AttributeBase);
doSomeThing(MyStaticChild.AttributeChild);
// ...
Создателю статического потомка не нужно думать о процессе сериализации, если он понимает любые ограничения, которые могут быть наложены на механизм сериализации платформы или среды.
Статика (синглтоны и другие формы глобалов) часто возникает вокруг хранилища конфигурации. Статическое наследование позволило бы четко представить такое распределение ответственности в синтаксисе, чтобы оно соответствовало иерархии конфигураций. Хотя, как я показал, существует большой потенциал для неоднозначности, если реализовать базовые концепции статического наследования.
Я считаю, что правильным выбором дизайна было бы позволить статическое наследование с конкретными ограничениями:
- Нет переопределения ничего. Дочерний объект не может заменить базовые атрибуты, поля или методы, ... Перегрузка должна быть в порядке, если есть разница в сигнатуре, позволяющая компилятору разобраться с дочерним и базовым.
- Разрешить только общие статические базы, вы не можете наследовать от неуниверсальных статических баз.
Вы все еще можете изменить тот же магазин через общую ссылку MyStaticBase<ChildPayload>.SomeBaseField
. Но вы были бы обескуражены, так как общий тип должен быть указан. Пока ссылка на ребенка будет чище:MyStaticChild.SomeBaseField
.
Я не пишу компилятор, поэтому я не уверен, что что-то упускаю из-за трудностей реализации этих ограничений в компиляторе. Тем не менее, я твердо убежден, что информационное пространство необходимо для ограниченного статического наследования, и основной ответ заключается в том, что вы не можете этого сделать из-за плохого (или слишком простого) выбора дизайна.