Почему статические классы считают “классами” и “ссылочными типами”?

Я обдумывал о C# и системе типов CIL сегодня, и я начал задаваться вопросом, почему статические классы считают классами. Существует много путей, которыми они не действительно классы:

  • “Нормальный” класс может содержать нестатических участников, статический класс не может. В этом отношении класс более подобен структуре, чем это к статическому классу, и все же структуры имеют отдельное имя.
  • У Вас может быть ссылка на экземпляр “нормального” класса, но не статического класса (несмотря на него рассматриваемый “ссылочным типом”). В этом отношении класс более подобен интерфейсу, чем это к статическому классу, и все же интерфейсы имеют отдельное имя.
  • Название статического класса никогда не может использоваться ни в каком месте, где имя типа обычно соответствовало бы: Вы не можете объявить переменную этого типа, Вы не можете использовать его в качестве базового типа, и Вы не можете использовать его в качестве универсального параметра типа. В этом отношении статические классы несколько больше похожи на пространства имен.
  • “Нормальный” класс может реализовать интерфейсы. Еще раз это делает классы более подобными структурам, чем к статическим классам.
  • “Нормальный” класс может наследоваться другому классу.

Также странно, что статические классы, как полагают, происходят из Системы. Объект. Хотя это позволяет им “наследоваться”, статические методы Равняется и ReferenceEquals, цель того наследования сомнительна, как Вы назвали бы те методы на объекте так или иначе. C# даже позволяет Вам указывать что бесполезное наследование явно на статических классах, но не в интерфейсах или структурах, где неявная деривация из объекта и Системы. ValueType, соответственно, на самом деле имеет цель.

Относительно аргумента подмножества функций: Статические классы имеют подмножество функций классов, но у них также есть подмножество функций структур. Все вещи, которые делают класс отличным от других видов типа, кажись, не относиться к статическим классам.

Относительно typeof аргумента: Превращение статического класса в новый и другой вид типа не устраняет его от того, чтобы быть используемым в typeof.

Учитывая чистую причуду статических классов и дефицит общих черт между ними и “нормальными” классами, разве они не должны были быть превращены в отдельный вид типа вместо специального вида класса?

23
задан 2 revs 6 May 2010 в 12:44
поделиться

9 ответов

Да, они очень странные. У них действительно есть некоторое классовое поведение, например, возможность иметь (статические) переменные-члены и ограничивать доступ к членам, использующим общедоступные / частные.

Я почти набрал там «общедоступный / защищенный / частный», но очевидно, что защищенный не имеет смысла, потому что нет наследования методов статических классов. Я думаю, что основная причина этого в том, что из-за отсутствия экземпляров у вас не может быть полиморфизма, но на самом деле это не единственная причина наследования. Полиморфизм - это замечательно, но иногда вы просто хотите позаимствовать большую часть функциональности базового класса и добавить несколько собственных вещей. Из-за этого иногда вы увидите, что статические классы переключаются на использование одноэлементных шаблонов просто для того, чтобы они могли использовать некоторые функции из базового набора классов. На мой взгляд, это хакерская попытка восполнить этот пробел, она сбивает с толку и вносит много неестественной сложности. Другой вариант - агрегация, когда методы дочернего класса просто передают вызовы методам родительского класса, но для этого требуется много кода, чтобы объединить все вместе, и это тоже не идеальное решение.

В наши дни статические классы обычно используются просто как замена глобальным методам, то есть методам, которые просто обеспечивают функциональность, не будучи привязанными к экземпляру чего-либо. Сторонники объектно-ориентированного подхода ненавидят любую концепцию свободного / глобального чего-либо, плавающего вокруг, но вы также не хотите иметь ненужный экземпляр и объект, плавающий вокруг, если вам просто нужна функциональность, поэтому статический «класс» обеспечивает компромисс. компромисс, с которым могут согласиться обе стороны.

Так что да, статические классы странные. В идеале было бы неплохо, если бы они могли быть разбиты на свою собственную концепцию, обеспечивающую гибкость и легкую простоту использования, которые вы получаете от методов, которые не должны быть привязаны к экземпляру (который у нас теперь со статическими классами ), а также сгруппировать эти методы в контейнеры (которые у нас также есть сейчас), но также предоставить возможность определять базовый объект, от которого он будет наследовать методы (это часть, которая сейчас отсутствует). Кроме того, было бы здорово, если бы это была отдельная концепция от классов, именно по причинам, о которых вы говорите, это просто сбивает с толку, потому что люди, естественно, ожидают, что классы будут экземплярами со свойствами и методами, которые можно создавать и уничтожать.

4
ответ дан 29 November 2019 в 02:48
поделиться

А как насчет статических конструкторов? Я думаю, что это еще один важный аспект, который следует учитывать при сравнении. Классы и структуры поддерживают их, а интерфейсы и пространства имен - нет.

Конструкция подразумевает создание экземпляра. Хотя реализация может фактически не создавать «экземпляр» статического класса, вы можете рассматривать статические классы как одноэлементный экземпляр класса, на который может быть только одна ссылка (само имя типа). Если бы вы могли наследовать статические классы, вы бы нарушили понятие синглтона. Если бы вы могли объявить переменные этого типа, вы могли бы ожидать, что они будут очищены сборщиком мусора, когда на них больше не будет ссылаться.

Почему это классы, а не структуры? Когда я думаю о структурах (типах значений), я думаю о значениях в стеке. Их существование (как правило) очень короткое, и их часто копируют. Это снова нарушает указанное выше понятие одиночной ссылки.

-1
ответ дан 29 November 2019 в 02:48
поделиться

Хорошее замечание, возможно, это связано с историческими причинами, т.е. они не хотели изобретать что-то новое, поскольку статические классы уже существовали.

C++, Pascal (Delphi) и Java имеют статические классы, и именно на них основан C#.

0
ответ дан 29 November 2019 в 02:48
поделиться

С точки зрения среды CLR это класс. По сути, это просто синтаксический сахар в компиляторе C #.

Я не думаю, что добавление здесь другого имени принесет какую-то пользу - они ведут себя в основном как классы, которые имеют только статические методы и не могут быть построены, что обычно является типом класса. который стал статическим классом, когда мы перешли с C # 1 на C # 2.

Имейте в виду, что если вы хотите создать для него новое имя, это, вероятно, также означает новое ключевое слово ...

8
ответ дан 29 November 2019 в 02:48
поделиться

Я не знаю, можно ли это квалифицировать как ответ, но я хотел бы отметить, что «статические классы» - это скорее концепция языка, а не среда CLR. концепция. С точки зрения CLR это просто классы, как и все остальные. Это зависит от языка, чтобы обеспечить соблюдение всех описанных вами правил.

Таким образом, одно из преимуществ текущей реализации состоит в том, что она не добавляет дополнительной сложности к CLR, которую все языки с таргетингом на CLR должны понимать и моделировать.

4
ответ дан 29 November 2019 в 02:48
поделиться

Статические классы и "нормальные" классы (и структуры) являются контейнерами для исполняемого кода (поля-члены, свойства, методы), и они объявляют тип. Если бы для них было отдельное слово, то мы бы спросили обратное ("если они так похожи, почему вы не использовали класс kayword?"). Я бы посоветовал "CLR через C#", где хорошо объясняется, как происходит разрешение типов, вызов методов и т.д. Это работает одинаково для "обоих" классов, просто члены экземпляра имеют дополнительный параметр, передаваемый для объекта экземпляра.

Классы не похожи на пространства имен, потому что они служат только для именования и ссылок. Они не влияют на функциональность класса.

Классы также отличаются от интерфейсов, потому что интерфейсы являются лишь инструментами проверки во время компиляции и не имеют собственной функциональности.

0
ответ дан 29 November 2019 в 02:48
поделиться

На мой взгляд, статические классы считаются такими, потому что они могут встраивать частные поля, общедоступные свойства и методы, хотя они статичны и имеют фиксированное расположение адреса, в котором каждый вызов одноэлементный метод или свойство будет иметь ссылку.

Структура более вероятно является типом значения, например, когда вы пишете:

var struct1 = new Struct1();
var struct2 = struct1;

каждое из свойств будет скопировано в новое место в памяти.Кроме того, с помощью структуры вы сможете изменить значение struct2.Property1 без его изменения в struct1.Property1.

В моем понимании классы являются ссылочными типами, например, когда вы пишете:

var class1 = new Class1();
var class2 = class1;

Здесь ссылка копируется. Это означает, что при изменении class2.Property1 это же свойство также изменится в class1.Property1. Это потому, что оба класса указывают на один и тот же адрес памяти.

Что касается статических классов, они считаются ссылочными типами, поскольку, когда вы изменяете значение StaticClass.Property внутри метода, это изменение будет заполняться везде, где вы ссылаетесь на этот класс. Он имеет только один адрес памяти и не может быть скопирован, поэтому при вызове другого метода или свойства это новое значение будет преобладать над старым. Статические классы предназначены для совместного использования во всем приложении, поэтому в вашем приложении существует только одна ссылка на них. Поэтому заставляю их вести себя как класс.

Статический класс, даже несмотря на то, что одноэлементный шаблон, я полагаю, не поощряется, кроме как для абсолютной цели, может представлять реальный объект точно так же, как класс или экземпляр класса. Однако, поскольку уникальные в мире объекты кажутся достаточно редкими, нам на самом деле не нужны они для представления практического объекта, а вместо этого нужны лишь некоторые логические объекты, такие как инструменты и т. Д., Или некоторые другие дорогостоящие объекты. создавать объекты.

РЕДАКТИРОВАТЬ Фактически, статический класс настолько похож на класс, что в Visual Basic нет статического класса, а есть только класс со статическими (совместно используемыми в Visual Basic) членами.Единственное, что следует учитывать, - сделать этот класс NotInheritable (запечатанным на C #). Итак, C # предоставляет более неявную функциональность, позволяя объявлять класс static вместо того, чтобы делать его запечатанным, с пустым конструктором по умолчанию и т. Д. Это своего рода ярлык или синтаксический сахар, как мы любим говорить.

В заключение, я не думаю, что новое ключевое слово принесет какую-то пользу.

0
ответ дан 29 November 2019 в 02:48
поделиться

Ваш вопрос: "Почему я должен набирать слова static class X, а не foobar X". Ответ: потому что у программистов слово "класс" уже ассоциируется с "пучком плотно упакованной инкапсулированной функциональности, которую кто-то написал для меня". Что, по совпадению, идеально подходит к определению статических классов.

Они могли бы использовать пространства имен вместо этого, да. Так и происходит в C++. Но термин "статический класс" имеет здесь преимущество: он подразумевает меньшую и гораздо более тесно связанную группу функциональности. Например, вы можете иметь пространство имен Qt или boost::asio, но статический класс под названием StringUtils или KWindowSystem (заимствование из KDE).

7
ответ дан 29 November 2019 в 02:48
поделиться

Конечно, из них можно было сделать отдельный вид вещей.

Но это потребовало бы дополнительной работы в CLR, BCL и во всех языковых командах, и я оставил бы другие, более важные вещи невыполненными.

С чисто эстетической точки зрения могу с вами согласиться.

3
ответ дан 29 November 2019 в 02:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: