Должны ли методы C #, которые могут быть статическими, быть статическими?
Мы обсуждали это сегодня, и я как бы нахожусь в напряжении. Представьте, что у вас есть длинный метод, из которого вы реорганизуете несколько строк. Новый метод, вероятно, берет несколько локальных переменных из родительского метода и возвращает значение. Это означает, что он может быть статичным.
Вопрос в том, должен ли он быть статичным? Он не статичен по дизайну или выбору, просто по своей природе, поскольку он не ссылается ни на какие значения экземпляра.
Ответы:
Это зависит. На самом деле существует 2 типа статических методов:
В кодовой базе малого и среднего размера вы действительно можете рассматривать два метода как взаимозаменяемые.
Если у вас есть метод, относящийся к первой категории (может быть-статическим), и вам нужно изменить его для доступа к состоянию класса, довольно просто выяснить, можно ли превратить статический метод в метод экземпляра.
Однако в большой базе кода огромное количество сайтов вызова может сделать поиск, чтобы увидеть, возможно ли преобразовать статический метод в нестатический слишком дорогостоящим. Много раз люди увидят количество звонков и скажут: «Хорошо ... Мне лучше не менять этот метод, а вместо этого создать новый, который будет делать то, что мне нужно».
Это может привести к:
Обе эти вещи плохи.
Итак, я бы посоветовал, если у вас есть кодовая база более 200K LOC, я бы делал методы статическими только в том случае, если они должны быть статическими.
Рефакторинг от нестатического к статическому относительно легко (просто добавьте ключевое слово), поэтому, если вы хотите позже превратить статический статический в фактический статический (когда вам понадобится его функциональность вне экземпляра), вы можете. Однако обратный рефакторинг, превращающий статический метод в метод экземпляра, НАМНОГО дороже.
При больших базах кода лучше делать ошибки из-за простоты расширения, а не из-за идеологической чистоты.
Итак, для больших проектов не делайте вещи статичными, если они вам не нужны. Для небольших проектов просто делайте то, что вам больше нравится.
источник
Я бы не стал делать его публичным статическим членом этого класса . Причина в том, что создание общедоступного статического объекта говорит кое-что о типе класса: не только то, что «этот тип знает, как выполнять такое поведение», но также «ответственность этого типа за выполнение этого поведения». И, скорее всего, это поведение больше не имеет реальной связи с большим типом.
Это не значит, что я бы вообще не делал его статичным. Спросите себя: может ли новый метод логически принадлежать другому? Если вы можете ответить «да» на это, вы, вероятно, захотите сделать его статичным (а также переместить). Даже если это не так, вы все равно можете сделать его статичным. Только не помечай это
public
.Для удобства можно хотя бы пометить
internal
. Обычно это позволяет избежать необходимости перемещать метод, если у вас нет легкого доступа к более подходящему типу, но все же оставляет его доступным там, где это необходимо, таким образом, что он не будет отображаться как часть общедоступного интерфейса для пользователей вашего класса. .источник
Не обязательно.
Перемещение общедоступных методов из статических в нестатические - это критическое изменение, которое потребует изменений во всех ваших вызывающих или потребителях. Если метод выглядит как метод экземпляра, но не использует никаких членов экземпляра, я бы предложил сделать его методом экземпляра в качестве меры защиты от будущего.
источник
Да. Причина, по которой «он может быть статическим», заключается в том, что он не работает с состоянием объекта, для которого он вызван. Следовательно, это не метод экземпляра, а метод класса. Если он может делать то, что ему нужно, без доступа к данным экземпляра, то он должен быть статическим.
источник
Да, должно. Существуют различные метрики связи, которые измеряют, как ваш класс зависит от других вещей, таких как другие классы, методы и т. Д. Создание статических методов - это способ снизить степень связи, поскольку вы можете быть уверены, что статический метод не ссылается ни на какие члены.
источник
Я думаю, что это сделало бы его более читаемым, если бы вы пометили его как статический ... Тогда кто-нибудь, кто придет, узнает, что он не ссылается ни на какие переменные экземпляра, не читая всю функцию ...
источник
Лично я большой поклонник безгражданства. Вашему методу нужен доступ к состоянию класса? Если ответ отрицательный (и, вероятно, нет, иначе вы бы не стали рассматривать его как статический метод), тогда да, сделайте это.
Нет доступа к состоянию - меньше головной боли. Так же, как это хорошая идея - скрыть частные члены, которые не нужны другим классам, это хорошая идея - скрыть состояние от членов, которым оно не нужно. Ограниченный доступ может означать меньше ошибок. Кроме того, это упрощает многопоточность, поскольку намного проще поддерживать потокобезопасность статических элементов. Также необходимо учитывать производительность, поскольку среде выполнения не нужно передавать ссылку на this в качестве параметра для статических методов.
Конечно, недостатком является то, что если вы когда-нибудь обнаружите, что ваш ранее статический метод по какой-то причине должен будет получить доступ к состоянию, вам придется его изменить. Теперь я понимаю, что это может быть проблемой для общедоступных API, поэтому, если это общедоступный метод в общедоступном классе, возможно, вам стоит немного подумать о последствиях этого. Тем не менее, я никогда не сталкивался с ситуацией в реальном мире, когда это действительно вызывало проблемы, но, возможно, мне просто повезло.
Так что да, дерзайте во что бы то ни стало.
источник
Статические методы быстрее, чем нестатические, поэтому да, они должны быть статическими, если могут, и нет особых причин оставлять их нестатическими .
источник
Я удивлен, что на самом деле здесь так мало упоминается инкапсуляция. Метод экземпляра автоматически получит доступ ко всем частным (экземпляровым) полям, свойствам и методам. Помимо всех защищенных, унаследованных от базовых классов.
Когда вы пишете код, вы должны писать его так, чтобы вы открывали как можно меньше, а также чтобы у вас был доступ как можно меньше.
Так что да, может быть важно сделать ваш код быстрым, что произойдет, если вы сделаете свои методы статическими, но обычно более важно, чтобы ваш код также был как можно более неспособным создавать ошибки. Один из способов добиться этого - сделать так, чтобы ваш код имел доступ к как можно меньшему количеству «личных вещей».
На первый взгляд это может показаться неуместным, так как OP, очевидно, говорит о рефакторинге, который не может пойти не так в этом сценарии и создать какие-либо новые ошибки, однако этот реорганизованный код должен быть сохранен в будущем и изменен, что делает ваш код более сильным поверхность »в отношении новых ошибок, если у нее есть доступ к частным членам экземпляра. В общем, я думаю, что вывод состоит в том, что «да, в основном ваши методы должны быть статическими», если нет других причин, по которым они не статичны. И это просто потому, что это «лучшее использование инкапсуляции и сокрытия данных и создание« более безопасного »кода» ...
источник
Делать что-то статичное только потому, что вы можете, - не лучшая идея. Статические методы должны быть статичными из-за их конструкции, а не из-за случайности.
Как сказал Майкл, изменение этого позже нарушит код, который его использует.
С учетом сказанного, похоже, что вы создаете частную служебную функцию для класса, которая, по сути, является статической по дизайну.
источник
Если вам удалось провести рефакторинг нескольких строк, и результирующий метод может быть статическим, это, вероятно, указывает на то, что строки, которые вы вытащили из этого метода, вообще не принадлежат содержащему классу, и вам следует подумать о перемещении их в свой класс.
источник
Лично у меня не было бы выбора, кроме как сделать его статичным. В этом случае Resharper выдает предупреждение, а в нашем личном кабинете есть правило «Нет предупреждений от Resharper».
источник
Это зависит от обстоятельств, но обычно я не делаю эти методы статичными. Код всегда меняется, и, возможно, однажды я захочу сделать эту функцию виртуальной и переопределить ее в подклассе. Или, возможно, когда-нибудь потребуется ссылка на переменные экземпляра. Внести эти изменения будет труднее, если придется менять каждый сайт вызова.
источник
Я предполагаю, что лучший способ думать об этом заключается в следующем: если вам нужен метод класса, который нужно вызывать, когда экземпляры класса не создаются, или поддерживает какое-то глобальное состояние, тогда static - хорошая идея. Но в целом я предлагаю вам сделать члены нестатичными.
источник
Вы должны подумать о своих методах и классах:
Если последние два - «да», то ваш метод / класс, вероятно, должен быть статическим.
Наиболее часто используемый пример - это
Math
класс. Он есть во всех основных объектно-ориентированных языках, и все методы статичны. Потому что вам нужно иметь возможность использовать их где угодно и когда угодно, без создания экземпляра.Еще один хороший пример -
Reverse()
метод на C #.Это статический метод в
Array
классе. Он меняет порядок вашего массива.Код:
Он даже ничего не возвращает, ваш массив перевернут, потому что все массивы являются экземплярами класса Array.
источник
Пока вы делаете новый метод закрытым статическим, это не критическое изменение. Фактически, FxCop включает это руководство как одно из своих правил ( http://msdn.microsoft.com/en-us/library/ms245046(VS.80).aspx ) со следующей информацией:
При этом первый комментарий Дэвида Кина более кратко резюмирует опасения, говоря, что это на самом деле больше о правильности, чем о приросте производительности:
источник
Я бы определенно превратил все, что могу, в статическое по другой причине:
Статические функции при выполнении JIT вызываются без параметра this. Это означает, например, что нестатическая функция с 3 параметрами (метод-член) помещается в стек с 4 параметрами.
Та же функция, скомпилированная как статическая, будет вызываться с 3 параметрами. Это может освободить регистры для JIT и сэкономить пространство стека ...
источник
Я нахожусь в лагере "только статические частные методы". Создание общедоступного метода может привести к нежелательному связыванию и снижению тестируемости: вы не можете заглушить общедоступный статический метод.
Если вы хотите провести модульное тестирование метода, использующего общедоступный статический метод, вы в конечном итоге протестируете и статический метод, что может быть не тем, что вам нужно.
источник
По своей сути статические методы, которые по какой-то причине сделаны нестатическими, просто раздражают. А именно:
Я звоню в свой банк и спрашиваю свой баланс.
Они спрашивают номер моего счета.
Справедливо. Метод экземпляра.
Я звоню в свой банк и спрашиваю их почтовый адрес.
Они спрашивают номер моего счета.
Какого черта? Неудача - должен был быть статический метод.
источник
Я смотрю на это вообще с функциональной точки зрения чистых функций. Это должен быть метод экземпляра? Если нет, вам может быть полезно заставить пользователя передавать переменные, а не изменять текущее состояние экземпляра. (Что ж, вы все равно можете искажать состояние, но суть в том, чтобы не делать этого по замыслу.) Я обычно проектирую методы экземпляра как открытые члены и стараюсь сделать частные члены статичными. При необходимости (позже их можно будет легко извлечь в другие классы.
источник
В таких случаях я стараюсь перенести метод в статическую библиотеку или библиотеку utils, поэтому я не смешиваю концепцию «объекта» с концепцией «класса».
источник