Должны ли статические статические методы C #, которые * могут быть статическими?

Должны ли статические статические статические методы C #?

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

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

Это зависит. Есть действительно 2 типа статических методов:

  1. Методы, которые являются статическими, поскольку они МОГУТ быть
  2. Методы, статические, потому что они должны быть

В базе кода с небольшим и средним размером вы действительно можете рассматривать оба метода взаимозаменяемо.

Если у вас есть метод, который находится в первой категории (can-be-static), и вам нужно изменить его для доступа к состоянию classа, то довольно просто выяснить, можно ли превратить статический метод в метод экземпляра.

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

Это может привести к:

  1. Много дублирования кода
  2. Взрыв числа аргументов метода

Обе эти вещи плохи.

Итак, мой совет будет заключаться в том, что если у вас есть база кода более 200 тыс. LOC, я бы только ставил методы статическими, если они являются обязательными статическими методами.

Рефакторинг от нестатического к статическому относительно легко (просто добавьте ключевое слово), поэтому, если вы хотите сделать статическую статическую в фактическую статику позже (когда вам нужна ее функциональность за пределами экземпляра), то вы можете. Тем не менее, обратный рефакторинг, превращающий can-be-static в метод экземпляра, намного дороже.

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

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

Я бы не стал публичным статическим членом этого classа . Причина в том, что сделать его public static говорит что-то о типе classа: не только это «этот тип знает, как это сделать», но также «ответственность за это поведение несет именно этот тип». И вероятность того, что поведение больше не имеет реальных отношений с более крупным типом.

Это не значит, что я бы не стал статичным вообще. Спросите себя: может ли новый метод логически принадлежать другому? Если вы можете ответить «да» на это, вы, вероятно, захотите сделать его статическим (и переместить его также). Даже если это не так, вы все равно можете сделать его статичным. Просто не отмечайте это public .

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

Не обязательно.

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

Да. Причиной «он может быть статичным» является то, что он не работает с состоянием объекта, на который он вызван. Поэтому это не метод экземпляра, а метод classа. Если он может делать то, что ему нужно, без доступа к данным для экземпляра, то он должен быть статическим.

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

Я думаю, что это сделало бы его более читаемым, если бы вы отметили его как статичное … Тогда кто-то, кто приходит, будет знать, что он не ссылается ни на переменные экземпляра, не имея необходимости читать всю функцию …

Лично я большой поклонник безгражданства. Требуется ли вашему методу доступ к состоянию classа? Если ответ отрицательный (и, вероятно, нет, в противном случае вы не считаете его статическим методом), то да, идите на это.

Отсутствие доступа к состоянию – это меньше головной боли. Так же, как хорошая идея скрыть частных членов, которые не нужны другим classам, неплохо скрыть состояние от членов, которые не нуждаются в этом. Уменьшенный доступ может означать меньше ошибок. Кроме того, он упрощает процесс нарезания резьбы, так как гораздо проще сохранять статические элементы в streamовом режиме. Существует также оценка производительности, так как во время выполнения не требуется передавать ссылку на это как параметр для статических методов.

Конечно, недостатком является то, что если вы когда-нибудь обнаружите, что ваш прежний статический метод по какой-то причине должен получить доступ к состоянию, вам придется его изменить. Теперь я понимаю, что это может быть проблемой для общедоступных API, поэтому, если это общеansible метод в открытом classе, то, возможно, вам стоит подумать о последствиях этого. Тем не менее, я никогда не сталкивался с ситуацией в реальном мире, где это фактически вызвало проблему, но, возможно, мне просто повезло.

Так что да, идите на это, во что бы то ни стало.

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

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

Как сказал Майкл, изменение этого позже приведет к слому кода, который его использует.

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

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

Я удивлен, что на самом деле так мало упоминается инкапсуляция. Метод экземпляра автоматически получит доступ ко всем частным (экземплярам) полям, свойствам и методам. В дополнение ко всем защищенным, унаследованным от базовых classов.

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

Так что да, может быть очень важно быстро сделать ваш код, если бы вы делали ваши методы статичными, но обычно более важно то, чтобы сделать ваш код так же неспособным создавать ошибки, насколько это возможно. Один из способов добиться этого – иметь доступ к вашему коду как можно меньше от «частного материала».

Это может показаться нерелевантным с первого взгляда, поскольку OP, очевидно, говорит о рефакторинге, который не может ошибиться в этом сценарии и создавать любые новые ошибки, однако этот обновленный код должен поддерживаться в будущем и модифицироваться, что делает ваш код более крупной атакой поверхности “в отношении новых ошибок, если он имеет доступ к частным членам экземпляра. Поэтому в целом я думаю, что вывод здесь заключается в том, что «да в основном ваши методы должны быть статическими», если нет других причин, по которым они не статичны. И это просто потому, что «лучше использовать инкапсуляцию и скрывать данные и создает« безопасный »код» …

Лично у меня не было бы выбора, кроме как сделать его статичным. В этом случае Resharper выдает предупреждение, и у нашего PM есть правило «Нет предупреждений от Resharper».

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

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

Вы должны думать о своих методах и classах:

  • Как вы собираетесь их использовать?
  • Вам нужно много доступа к ним с разных уровней кода?
  • Является ли это методом / classом, который я могу использовать практически в каждом мыслимом проекте.

Если последние два являются «да», то ваш метод / class должен быть, вероятно, статичным.

Наиболее часто используемый пример – это, вероятно, class Math . У каждого основного языка OO есть это, и все методы статичны. Потому что вы должны иметь возможность использовать их в любом месте и в любое время без создания экземпляра.

Другим хорошим примером является метод Reverse() в C #.
Это статический метод в classе Array . Он меняет порядок вашего массива.

Код:

 public static void Reverse(Array array) 

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

Пока вы создаете новый метод private static, это не является нарушением изменений. Фактически, FxCop включает это руководство в качестве одного из своих правил ( http://msdn.microsoft.com/en-us/library/ms245046(VS.80).aspx ) со следующей информацией:

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

Это, как говорится, первый комментарий Дэвида Кина более кратко излагает проблемы, говоря, что на самом деле это больше касается правильности, чем увеличения производительности:

Хотя это правило classифицируется как проблема производительности, повышение производительности при создании статического метода составляет всего около 1%. Скорее, это скорее проблема правильности, которая может указывать либо на неполную, либо на ошибку в члене из-за неспособности использовать другие члены экземпляра. Маркировка метода static ( Shared в Visual Basic) дает понять, что он не намерен касаться состояния экземпляра.

Я бы определенно превратил все, что мог, в статику по другой причине:

Статические функции, когда JIT’d, вызываются без «этого» параметра. Это означает, например, что трехстатистическая нестатическая функция (метод-член) вводится с 4-мя параметрами в стеке.

Та же функция, скомпилированная как статическая функция, вызывается с тремя параметрами. Это может освободить регистры для JIT и сохранить пространство стека …

Я нахожусь в статичном лагере «только сделай приватные методы». Создание общедоступного метода может привести к сочетанию, которое вы не хотите, и может уменьшить тестируемость: вы не можете заглушить открытый статический метод.

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

Постоянные статические методы, которые по какой-то причине делают нестатические, просто раздражают. Для остроумия:

Я звоню в свой банк и спрашиваю о моем балансе.
Они запрашивают мой номер счета.
Справедливо. Метод экземпляра.

Я звоню в свой банк и спрашиваю их почтовый адрес.
Они запрашивают мой номер счета.
WTF? Ошибка – должен был быть статическим методом.

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

В этих случаях я склонен переместить метод в статическую или utils-библиотеку, поэтому я не смешиваю понятие «объект» с понятием «class»,

  • Почему не вызывает статический метод путем экземпляра ошибки для компилятора Java?
  • Разница между статическим classом и одноэлементным шаблоном?
  • Если частные вспомогательные методы являются статическими, если они могут быть статическими
  • Должен ли быть объявлен «статический конечный регистратор» в ВЕРХНЕЙ ЧАСТИ?
  • преобразование двумерного массива в указатель на указатель
  • Какова цель статического ключевого слова в параметре массива функции типа «char s »?
  • Статическая переменная шаблона
  • Разница между статическими и частными статическими переменными
  • Разница между статическими методами и методами экземпляра
  • Почему глобальные и статические переменные инициализируются значениями по умолчанию?
  • Существует ли static_warning?
  • Interesting Posts

    Как отсортировать ArrayList, используя несколько критериев сортировки?

    rails i18n – перевод текста со ссылками внутри

    Захват исключений из списка инициализаторов конструктора

    Как компьютер выполняет арифметику с плавающей запятой?

    Может ли код, который действителен как в C, так и в C ++, создает другое поведение при компиляции на каждом языке?

    Что это за формат даты? 2011-08-12T20: 17: 46.384Z

    Безопасно ли удалять USB-носители при приостановке работы компьютера?

    Возьмите сегмент массива в Java без создания нового массива в куче

    Как вставить дату в таблицу Excel?

    Как передать несколько аргументов в processStartInfo?

    Расширенная политика аудита безопасности не применяется к Win7

    Как реализовать wordwrap на jqGrid, который работает на IE7, IE8 и FF

    Ссылка на содержимое ячейки памяти. (режимы адресации x86)

    Как вы получаете общий объем оперативной памяти компьютера?

    Отключить встроенную автоматическую антивирусную проверку хром загруженных файлов

    Давайте будем гением компьютера.