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

import zipfile
Z = zipfile.ZipFile("alien-zip-2092.zip")
PASS = bytes("111", 'utf-8')
Z.extractall(pwd=PASS)
101
задан Peter Mortensen 19 December 2009 в 16:10
поделиться

21 ответ

Это зависит. На самом деле существует 2 типа статических методов:

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

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

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

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

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

  1. большому дублированию кода
  2. резкому увеличению числа аргументов метода

И то, и другое плохо.

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

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

При больших базах кода лучше делать ошибки из-за простоты расширения, а не из-за идеалогической чистоты.

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

59
ответ дан Scott Wisniewski 24 November 2019 в 04:41
поделиться

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

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

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

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

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

Код:

public static void Reverse(Array array)

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

1
ответ дан KdgDev 24 November 2019 в 04:41
поделиться

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

8
ответ дан Jason Punyon 24 November 2019 в 04:41
поделиться

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

6
ответ дан agnieszka 24 November 2019 в 04:41
поделиться

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

4
ответ дан Chris Shaffer 24 November 2019 в 04:41
поделиться

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

1
ответ дан Foredecker 24 November 2019 в 04:41
поделиться

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

-1
ответ дан Jhonny D. Cano -Leftware- 24 November 2019 в 04:41
поделиться

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

2
ответ дан Prankster 24 November 2019 в 04:41
поделиться

Здесь есть статья AskTom, которая может помочь. Из статьи:

«Мне было интересно, почему операторы DDL не выполняются внутри автономной транзакции (как это делают последовательности), поэтому они не влияют на ожидающую пользовательскую транзакцию ...

Вы можете уточнить?

Продолжение 24 июня 2003 г. - 7:00 США / Восток:

это было бы так же «запутанно», как если бы не делать это таким образом. В любом случае, у вас есть atrans, так что если хотите, можете. »

Итак, если вы действительно, вы можете вставить свой DDL в автономную транзакцию и делать то, что вы хотите. Суть в том, что если вы не пойдете на явную длину, чтобы «подорвать» Oracle, DDL выполнит коммит. Тем не менее, если вам абсолютно необходимо, чтобы фиксация выполнялась в определенный момент, почему бы просто не выполнить ее явно?

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

1
ответ дан Brian Ensink 24 November 2019 в 04:41
поделиться

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

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

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

4
ответ дан 17 of 26 24 November 2019 в 04:41
поделиться

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

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

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

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

6
ответ дан Tamas Czinege 24 November 2019 в 04:41
поделиться

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

12
ответ дан Jabe 24 November 2019 в 04:41
поделиться

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

13
ответ дан JP Alioto 24 November 2019 в 04:41
поделиться

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

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

20
ответ дан Michael 24 November 2019 в 04:41
поделиться

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

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

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

43
ответ дан Joel Coehoorn 24 November 2019 в 04:41
поделиться

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

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

1
ответ дан Lennaert 24 November 2019 в 04:41
поделиться

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

Статические функции, когда JIT , вызываются без параметра "this". Это означает, например, что 3-параметрическая нестатическая функция (метод-член) в стек помещается 4 параметра.

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

1
ответ дан damageboy 24 November 2019 в 04:41
поделиться

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

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

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

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

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

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

4
ответ дан Thomas Hansen 24 November 2019 в 04:41
поделиться

As long as you make the new method private static it is not a breaking change. In fact, FxCop includes this guidance as one of its rules (http://msdn.microsoft.com/en-us/library/ms245046(VS.80).aspx), with the following information:

After you mark the methods as static, the compiler will emit non-virtual call sites to these members. Emitting non-virtual call sites will prevent a check at runtime for each call that ensures that the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue.

That being said, the first comment from David Kean more succinctly summarizes the concerns by saying this is actually more about being correct than about the performance gain:

Although this rule is classified as a performance issue, the performance improvement of making a method static is only around 1%. Скорее, это скорее проблема правильности, которая может указывать либо на неполное, либо на ошибку в элементе из-за его неспособности использовать другие элементы экземпляра. Пометка метода static ( Shared в Visual Basic) проясняет его намерение не касаться состояния экземпляра.

1
ответ дан Scott Dorman 24 November 2019 в 04:41
поделиться

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

0
ответ дан 24 November 2019 в 04:41
поделиться

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

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

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

1
ответ дан 24 November 2019 в 04:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: