Метод может быть сделан статическим, но должен ли он?

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

Ответы

Ответ 1

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

Правило CA1822 в FxCop или Code Analysis:

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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

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

Ответ 5

Просто чтобы добавить к @Jason True answer, важно понять, что просто ставить статичность на метод не гарантирует, что метод будет "чистый". Он будет неактивен в отношении класса, в котором он объявлен, но он может получить доступ к другим "статическим" объектам, которые имеют состояние (конфигурация приложения и т.д.), Это не всегда может быть плохой, но одна из причин, Я лично предпочитаю статические методы, когда могу, так это то, что если они чисты, вы можете тестировать и рассуждать о них изолированно, не беспокоясь о окружающем состоянии.

Ответ 6

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

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

Ответ 7

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

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

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

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

Ответ 8

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

Ответ 9

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

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

Ответ 10

Это помогает контролировать загрязнение пространства имен.

Ответ 11

Если функции распределены между несколькими страницами, вы также можете поместить их в базовый класс страницы, а затем все страницы asp.net, использующие эту функцию, наследуют от него (а также функции могут быть также статическими). ​​

Ответ 12

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

Ответ 13

Просто моя tuppence: добавление всех общих статических методов в класс утилиты позволяет вам добавить

using static className; 

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

Я понятия не имею, является ли это хорошей практикой или нет. У меня есть так много, чтобы узнать о С# 4/5 и так много устаревшего кода для рефакторинга, что я просто пытаюсь дать советы Roselyn направить меня.

Джои