В С#, какова цель пометки класса как статического?

В С#, какова цель пометки класса как статического?

Если у меня есть класс, который имеет только статические методы, я могу пометить класс как статический или нет. Почему я хочу пометить класс как статический? Захочу ли я когда-либо НЕ помечать класс как статический, если все методы являются статическими, и если я планирую никогда не добавлять нестатический метод?

Я огляделся и увидел несколько похожих вопросов, но ни один из них не был похож на этот.


person Cheeso    schedule 11.02.2010    source источник
comment
stackoverflow.com/ вопросов/576853/ stackoverflow.com/questions/241339/   -  person Jørn Schou-Rode    schedule 12.02.2010
comment
Задай свой вопрос, @dboarman!   -  person Cheeso    schedule 13.02.2010
comment
не волнуйтесь, не хотел бы загрязнять ваш вопрос. Думал, кто-то может прокомментировать потокобезопасность статических членов. ;)   -  person IAbstract    schedule 13.02.2010


Ответы (5)


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

Другие преимущества

  • Методы расширения могут быть определены только в статических классах.
  • Запрещает пользователям создавать экземпляр класса
  • Предотвращает использование типа в качестве универсального аргумента (спасибо, Эрик!)
person JaredPar    schedule 11.02.2010
comment
Это также не позволяет потребителям создавать экземпляр класса. До введения статических классов вам приходилось создавать закрытый конструктор без аргументов, чтобы реализовать это. - person Joel Mueller; 12.02.2010
comment
Между прочим, создание статического класса также предотвращает использование типа в качестве аргумента универсального типа в универсальном классе, структуре, интерфейсе, делегате или методе. (Что бы вы сделали с таким типом в качестве аргумента универсального типа? Вы не можете создать его, поэтому никакая переменная этого типа никогда не будет не нулевой. Вы не можете вызывать статические методы через параметр типа. Это было бы совершенно бесполезно, поэтому мы не разрешаем это.) - person Eric Lippert; 12.02.2010
comment
Это также невозможно вывести из него (по крайней мере, я не знаю, может быть, вы можете написать свой собственный IL, который делает или что-то в этом роде), что, я думаю, довольно очевидно :) - person Skurmedel; 12.02.2010
comment
@ Эрик, интересно, я не знал об общем предотвращении аргументов - person JaredPar; 12.02.2010
comment
@Skurmedel: статический класс фактически реализуется путем создания класса, метаданные которого помечены как запечатанные и абстрактные. Так что нет, вы не можете вывести его даже с помощью трюков с IL, потому что он запечатан. - person Eric Lippert; 12.02.2010
comment
Я бы хотел, чтобы интерфейсы были неявно static типами, чтобы они могли содержать static членов. - person Jay Bazuzi; 12.02.2010

Пометка класса как static дает вам две важные вещи.

  • Проверка компилятором того, что вы поместили в класс только static членов.

  • Очевидное утверждение для читателей вашего кода, что этот класс является только контейнером для static членов.

Эта функция была изобретена в ответ на ошибку в NDP v1.0, где a не вызываемый не-static член был включен в System.Environment класс.

person Jay Bazuzi    schedule 11.02.2010
comment
Кроме того: я хотел бы иметь аналогичный модификатор readonly для типов, который требует, чтобы все поля были помечены readonly и имели типы, помеченные readonly. NDP должен быть соответствующим образом аннотирован, особенно примитивные типы. К сожалению, большой объем кода написан с изменяемыми идиомами (например, List<T>, так что уже слишком поздно. - person Jay Bazuzi; 12.02.2010

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

person Yuriy Faktorovich    schedule 11.02.2010

Это соглашение относится к языку C#, CLR не имеет понятия о статических классах. Это гарантирует, что вы не сможете случайно добавить член экземпляра в класс, не сможете наследовать класс, а клиентский код не сможет случайно создать экземпляр класса. Базовыми атрибутами TypeAttributes для класса являются Abstract и Sealed. Abstract гарантирует, что новый оператор не сможет работать, Sealed гарантирует, что вы не сможете наследовать от класса.

Также по соглашению методы расширения должны быть статическими членами статического класса. VB.NET делает это по-другому, для этого требуется атрибут [Extension].

Использование статических классов в вашем коде не обязательно, но полезно. Их контракт очень описательный, он облегчает понимание вашего кода. Но будьте осторожны, чтобы не использовать их как средство для написания процедурного кода вместо кода ООП.

person Hans Passant    schedule 11.02.2010
comment
+1 за детали реализации и упоминание чрезмерного использования для написания процедурного кода. - person si618; 12.02.2010

Вы помечаете класс как статический, если хотите, чтобы он содержал только статические методы, типичный вспомогательный класс. Если вы поместите метод экземпляра, компилятор будет жаловаться - это хорошо. В версии 1 .NET Framework был класс, не помню какой, который должен был поставляться только со статическими методами. Случайно один из этих методов не получил модификатор static. Потому что этой функции не существовало в то время, когда ошибка была обнаружена очень поздно, уже после выпуска. Они сделали конструктор закрытым, и поэтому метод нельзя было использовать.

person Jorge Ferreira    schedule 11.02.2010