Метод можно сделать статичным, но так ли это? - PullRequest
345 голосов
/ 04 октября 2008

Resharper любит указывать на каждую страницу asp.net несколько функций, которые можно сделать статическими. Поможет ли мне сделать их статичными? Должен ли я сделать их статичными и переместить их в служебный класс?

Ответы [ 13 ]

249 голосов
/ 04 октября 2008

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

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

234 голосов
/ 04 октября 2008

Статические методы и методы экземпляра
10.2.5 Статические члены и члены экземпляра Спецификации языка C # объясняют разницу. Как правило, статические методы могут обеспечить очень небольшое повышение производительности по сравнению с методами экземпляра, но только в несколько экстремальных ситуациях (см. этот ответ для получения дополнительной информации об этом).

Правило CA1822 в состояниях FxCop или Code Analysis:

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

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

54 голосов
/ 04 октября 2008

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

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

21 голосов
/ 04 октября 2008

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

К сожалению, это были статические методы, которые принимали определенное состояние приложения. (почему, конечно, у нас будет только один пользователь на приложение! Почему бы классу User не отслеживать это в статических переменных?) Они были прославленными способами доступа к глобальным переменным. У них также были статические конструкторы (!), Что почти всегда было плохой идеей. (Я знаю, что есть несколько разумных исключений).

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

Просто убедитесь, что вы помещаете их в нужное место. Являются ли статические методы навязчиво манипулирующими внутренним состоянием других объектов? Можно ли доказать, что их поведение относится к одному из этих классов? Если вы не разделяете проблемы должным образом, возможно, у вас начнутся головные боли позже.

9 голосов
/ 19 июня 2012

Это интересно читать:

http://thecuttingledge.com/?p=57

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

но вот что говорит резче документация: http://confluence.jetbrains.net/display/ReSharper/Member+can+be+made+static

8 голосов
/ 03 сентября 2009

Просто добавьте к @Jason True's answer , важно понимать, что просто добавление «static» в метод не гарантирует, что метод будет «чистым». Он не будет иметь состояния в отношении класса, в котором он объявлен, но он вполне может обращаться к другим «статическим» объектам, которые имеют состояние (конфигурация приложения и т. Д.), Это не всегда плохо, но одна из причин того, что Лично я склонен отдавать предпочтение статическим методам, когда я могу, если они чистые, вы можете проверять и рассуждать о них изолированно, не беспокоясь об окружающем состоянии.

6 голосов
/ 16 октября 2009

Для сложной логики в классе я обнаружил, что частные статические методы полезны при создании изолированной логики, в которой входные данные экземпляров четко определены в сигнатуре метода, и побочные эффекты экземпляров не могут возникнуть. Все выходы должны быть через возвращаемое значение или параметры out / ref. Разбиение сложной логики на блоки кода без побочных эффектов может улучшить читабельность кода и доверие команды разработчиков к нему.

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

6 голосов
/ 04 октября 2008

Вы должны делать то, что наиболее читабельно и интуитивно понятно в данном сценарии.

Аргумент производительности не является хорошим, за исключением самых экстремальных ситуаций, поскольку единственное, что действительно происходит, - это то, что один дополнительный параметр (this) помещается в стек для методов экземпляра.

5 голосов
/ 06 февраля 2012

ReSharper не проверяет логику. Он только проверяет, использует ли метод элементы экземпляра. Если метод является закрытым и вызывается только (возможно, одним) методами экземпляра, это признак того, что он может быть методом экземпляра.

3 голосов
/ 04 октября 2008

Создание статического метода означает, что вы можете вызывать метод извне класса без предварительного создания экземпляра этого класса. Это полезно при работе с объектами сторонних поставщиков или надстройками. Представьте себе, если вам нужно было сначала создать консольный объект "con" перед вызовом con.Writeline ();

...