Когда использовать статические классы в C# [дубликат]



этот вопрос уже есть ответ здесь:



вот что MSDN должен сказать под когда использовать статические классы:




static class CompanyInfo
{
public static string GetCompanyName() { return "CompanyName"; }
public static string GetCompanyAddress() { return "CompanyAddress"; }
//...
}


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




Мне кажется, что этот пример не охватывает очень много возможных сценариев использования для статических классов. В прошлом я использовал статические классы для безгосударственные наборы связанных функций,но это все. Итак, при каких обстоятельствах класс должен (и не должен) быть объявлен статическим?

811   11  

11 ответов:

Я написал свои мысли о статических классах в более раннем ответе переполнения стека: класс с одним методом-лучший подход?

раньше я любил служебные классы, заполненные статическими методами. Они сделали большую консолидацию вспомогательных методов, которые в противном случае лежали бы вокруг, вызывая избыточность и ад обслуживания. Они очень просты в использовании, без создания экземпляров, без утилизации, просто fire'n'forget. Я думаю, это была моя первая невольная попытка создать сервис-ориентированная архитектура-множество служб без состояния, которые просто выполняли свою работу и ничего больше. Как система растет, однако, драконы приходят.

полиморфизм

скажем, у нас есть метод UtilityClass.Что-то, что счастливо гудит вместе. Внезапно нам нужно немного изменить функциональность. Большинство функций одинаковы, но мы должны изменить несколько частей, тем не менее. Если бы не статический метод, мы могли бы сделать производный класс и измените содержимое метода по мере необходимости. Конечно, если нам просто нужно добавить функциональность до или после старого метода, мы можем создать новый класс и вызвать старый внутри него - но это просто грубо.

беды интерфейс

статические методы не могут быть определены через интерфейсы по логическим причинам. И поскольку мы не можем переопределить статические методы, статические классы бесполезны, когда нам нужно передать их по своим взаимодействие. Это делает нас неспособными использовать статические классы как часть шаблона стратегии. Мы могли бы исправить некоторые проблемы до передача делегатов вместо интерфейсов.

тестирование

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

воспитывает капли

ползучести параметр

начнем с того, что маленький милый и невинный статический метод может принимать один параметр. По мере роста функциональности добавляется несколько новых параметров. Вскоре добавляются дополнительные параметры, которые являются необязательными, поэтому мы создаем перегрузки метода (или просто добавляем значения по умолчанию на языках, которые их поддерживают). Вскоре у нас есть метод, который принимает 10 параметров. Только первые три действительно необходимы, параметры 4-7 являются необязательными. Но если указан параметр 6, то необходимо также заполнить 7-9... Если бы мы создали класс с единственной целью сделать то, что сделал этот статический метод, мы могли бы решить эту проблему, взяв необходимые параметры в конструкторе и позволив пользователю устанавливать необязательные значения через свойства или методы для установки нескольких взаимозависимых значений одновременно. Кроме того, если метод вырос до такого уровня сложности, он, скорее всего, должен быть в своем собственном классе в любом случае.

требование потребителей создать экземпляр классов без причины

один из наиболее распространенных аргументов: зачем требовать, чтобы потребители нашего класса создавали экземпляр для вызова этого единственного метода, не имея никакого использования для экземпляра впоследствии? Создание экземпляра класса является очень дешевой операцией в большинстве языков, поэтому скорость не является проблемой. Добавление дополнительной строки кода потребителю-это низкая стоимость для закладки фундамента гораздо более ремонтопригодного решения в будущем. И, наконец, если вы хотите избежать создания экземпляров, просто создайте одноэлементную оболочку своего класса, которая позволяет легко использовать ее повторно, хотя это требует, чтобы ваш класс был без состояния. Если он не является безгосударственным, вы все равно можете создавать статические методы обертки, которые обрабатывают все, в то же время предоставляя вам все преимущества в долгосрочной перспективе. Наконец, вы также можете создать класс, который скрывает экземпляр, как если бы он был одноэлементным: MyWrapper.Экземпляр-это свойство, которое просто возвращает new MyClass();

Только ситхи все возводят в абсолют

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

стандарты, стандарты, стандарты!

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

при принятии решения о том, чтобы сделать класс статическим или нестатическим, вам нужно посмотреть, какую информацию вы пытаетесь представить. Это влечет за собой более 'снизу-вверх ' стиль программирования, где вы фокусируетесь на данных, которые вы представляете в первую очередь. Является ли класс, который вы пишете, реальным объектом, таким как камень или стул? Эти вещи являются физические и физические атрибуты, такие как цвет, вес, который говорит вам, что вы можете создать несколько объектов с разными свойства. Мне может понадобиться черный стул и красный стул одновременно. Если вам когда-нибудь понадобятся две конфигурации одновременно, вы сразу же узнаете, что хотите создать его как объект, чтобы каждый объект мог быть уникальным и существовать одновременно.

с другой стороны, статические функции имеют тенденцию предоставлять больше действий, которые не принадлежат реальному объекту или объекту, который вы можете легко представить. Помните, что предшественники C# - это C++ и C, где вы можете просто определить global функции, которые не существуют в классе. Это придает больше 'сверху вниз'. Статические методы могут быть использованы для этих случаев, когда не имеет смысла, что "объект" выполняет задачу. Заставляя вас использовать классы, это просто упрощает группировку связанных функций, которая помогает вам создавать более поддерживаемый код.

большинство классов могут быть представлены либо статическими, либо нестатическими, но когда вы сомневаетесь, просто вернитесь к своим корням ООП и попробуйте подумать о том, что вы представляете. Это объект, который выполняет действие (автомобиль, который может ускорить, замедлить, повернуть) или что-то более абстрактное (как отображение выходной).

войти в контакт с вашим внутренним ООП и вы никогда не ошибетесь!

для C# 3.0 методы расширения могут существовать только в статических классах верхнего уровня.

Если вы используете инструменты анализа кода (например,FxCop), он будет рекомендовать вам отметить метод static Если этот метод не обращается к данным экземпляра. Обоснование заключается в том, что есть прирост производительности. MSDN: CA1822-помечать членов как статические.

это скорее руководство, чем правило, на самом деле...

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

public static class Log
{
   private static readonly ILoggerFactory _loggerFactory =
      IoC.Resolve<ILoggerFactory>();

   public static ILogger For<T>(T instance)
   {
      return For(typeof(T));
   }

   public static ILogger For(Type type)
   {
      return _loggerFactory.GetLoggerFor(type);
   }
}

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

Я начал использовать статические классы, когда я хочу использовать функции, а не классы, как мой блок повторного использования. Раньше я был все о зле статических классов. Тем не менее, обучение F# заставило меня увидеть их в Новом Свете.

что я имею в виду? Ну, скажем, при разработке какой-то супер сухой код, я в конечном итоге с кучей классов одного метода. Я могу просто вытащить эти методы в статический класс, а затем ввести их в зависимости с помощью делегат. Это также хорошо играет с моим инъекции зависимостей (DI) контейнер выбора Autofac.

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

статические классы очень полезны и имеют место, например библиотек.

лучшим примером, который я могу предоставить, является класс .Net Math, статический класс пространства имен System, который содержит библиотеку математических функций.

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

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

C#.Net содержит ряд статических классов, которые используются так же, как математический класс.

поэтому при правильной реализации они чрезвычайно полезны.

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

Я использую статические классы как средство для определения "дополнительной функциональности", которую объект данного типа может использовать в определенном контексте. Обычно они оказываются служебными классами.

кроме этого, я думаю, что "использовать статический класс в качестве единицы организации для методов, не связанных с конкретных объектов.- опишите довольно хорошо их предполагаемое использование.

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

Я просто добавлю свои 2 цента к этому, сказав, что я делаю класс статическим, когда этот класс является чем-то уникальным в системе, и это действительно не имеет смысла иметь какие-либо экземпляры его в программе. Однако я резервирую это использование для больших классов. Я никогда не объявляю такие небольшие классы, как в Примере MSDN, как "статические" и, конечно же, не классы, которые будут членами других классов.

Я также хотел бы отметить, что статические методы и статический!--5-->классы это две разные вещи, чтобы рассмотреть. Основные недостатки, упомянутые в принятом ответе, относятся к статическому методы. статика классы предлагают ту же гибкость, что и обычные классы(где речь идет о свойствах и параметрах), и все методы, используемые в них, должны соответствовать цели существования класса.

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

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

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

на основе MSDN:

  1. вы не можете создать экземпляр для статических классов
  2. если класс объявлен как статический, переменная-член должна быть статической для этого класса
  3. запечатано [не может быть унаследовано]
  4. не может содержать конструктор экземпляра
  5. Управление Памятью

пример: математические вычисления (математические значения) не изменяется [стандартный расчет для определенных значений]

Comments

    Ничего не найдено.