Статические против нестатических членов класса - PullRequest
22 голосов
/ 29 марта 2012

Я новичок в C и программирую вообще. У меня есть быстрый вопрос - что является лучшей практикой в ​​отношении статических / нестатических переменных.

У меня есть переменная private int x, которая принадлежит классу y. Чтобы получить доступ к этой переменной, мне нужно сослаться на y. Однако, если x был статическим, я могу получить доступ к этой переменной без ссылок на y.

Каков наилучший путь в ситуации, когда несколько методов в классе y будут ссылаться на это значение?

Надеюсь, это имеет смысл, и мой вопрос не слишком прост!

Большое спасибо

Ответы [ 7 ]

46 голосов
/ 29 марта 2012

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

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

Если нет, используйте переменную экземпляра.

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

7 голосов
/ 29 марта 2012

Лучшая практика - избегать публичной статики.В ООП класс предназначен для сокрытия своих членов.На самом деле Static не является членом instance , а типа .

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

Вам нужно прочитать Статические классы и члены статических классов (Руководство по программированию в C #) .

4 голосов
/ 14 декабря 2012

Ну, я не могу окончательно сказать, что один лучше, потому что они служат различным целям.

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

C # следует аналогичным принципам для методов. К статическим методам можно обращаться напрямую из класса, в то время как к нестатическим методам (или методам экземпляра, как я их называю) нужно обращаться из экземпляра. Вот почему инстинктивность необходимо выполнять, например, для методов, в то время как для статических методов она просто не нужна и, кроме того, нецелесообразна (см. Ниже).

В ООП статические переменные используются для значений, которые не могут быть сохранены переменной экземпляра. Пример: предполагается, что вы хотите вести подсчет, сколько существует экземпляров класса? Как бы вы хранили это в одном экземпляре?

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

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

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

3 голосов
/ 29 марта 2012

Ваш выбор зависит от вашей архитектуры.

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

Кстати, в обоих случаях избегайте публичного показа fields, но используйте свойства.

1 голос
/ 16 ноября 2013

Я полностью согласен с г-ном Одедом :

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

Если нет, используйте переменную экземпляра.

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

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

Использование статических членов, когда глобальные переменные идут против OOP

Это означает, что, установив статический член, вы не сможете передать его как объект. Чем больше вы используете static в качестве глобального var, тем сложнее для модульного тестирования / mock ing classes .

Для этого есть решение, Одиночки . Но они никогда не должны прийти без предупреждений !

С другой стороны, если вы уверены , что вам действительно нужны глобальные переменные, взгляните на Toolbox pattern . Это не очень известное расширение шаблона Singleton. Это настолько неизвестно, на самом деле, если вы загляните в Google, вы не найдете его с этими ключевыми словами ( шаблон панели инструментов ).

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

0 голосов
/ 29 марта 2012

Вам нужно задать себе вопрос: зачем мне х быть статичным?

Если вы делаете x статическим, это означает, что x является частью всех объектов класса A, но когда x не является статическим, это означает, что x является частью только одного объекта.

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

Предлагаю взглянуть на использование сингелтона http://en.wikipedia.org/wiki/Singleton

0 голосов
/ 29 марта 2012

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

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

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

...