Какой смысл постоянной в C # - PullRequest
13 голосов
/ 28 марта 2010

Может кто-нибудь сказать, какой смысл постоянной в C #?

Например, в чем преимущество

const int months = 12;

в отличие от

int months = 12;

Я понял, что константы не могут быть изменены, но почему бы просто ... не изменить значение после его инициализации?

Ответы [ 14 ]

31 голосов
/ 28 марта 2010

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

Если вы объявляете pi константой, то каждый раз, когда он видит pi / 2, компилятор может выполнить вычисление и вставить 1,57 ... непосредственно в скомпилированный код. Если вы объявите pi в качестве переменной, то каждый раз, когда ваша программа использует pi / 2, компьютеру придется ссылаться на переменную pi и умножать ее на 0,5, что, очевидно, медленнее.

Я должен также добавить, что в C # есть readonly, который предназначен для значений, которые компилятор не может вычислить, но которые не могут изменяться в течение времени выполнения вашей программы. Например, если вам нужна константа ProgramStartTime, вам придется объявить ее readonly DateTime ProgramStartTime = DateTime.Now, потому что она должна быть оценена при запуске программы.

Наконец, вы можете создать свойство только для чтения, предоставив ему метод получения, но не установщик, например:

int Months { get { return 12; } } но, будучи свойством, оно не обязательно должно иметь одинаковое значение каждый раз, когда вы его читаете, например:

int DaysInFebruary { get { return IsLeapYear ? 29 : 28 } }

14 голосов
/ 28 марта 2010

Разница между «не может измениться» и «не изменится» действительно становится очевидной, только когда возникает одна из следующих ситуаций:

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

Очень похожие вопросы возникают при разговоре о доступности данных. Идея состоит в том, что вы хотите, чтобы ваш код предоставлял столько гибкости, сколько вы намереваетесь, потому что в противном случае кто-то (возможно, вы) придет и сделает что-то, чего вы не планировали, что приведет к ошибкам!

7 голосов
/ 28 марта 2010

Если вы никогда не совершаете ошибок, никто в вашей команде никогда не допускает ошибок, вы никогда не забудете точное назначение переменной, которую вы определили, даже после того, как вернетесь к коду, который вы не просматривали месяцами или годами, и вы, и все, с кем вы работаете на 100%, надежно распознают, понимают и следуют вашему намерению никогда не изменять значение const, если вы не удосужились использовать встроенную языковую конструкцию, которая одновременно четко указывает и применяет константу, то нет точка.

Если что-то из этого окажется не так, вот в чем дело.

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

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

3 голосов
/ 28 марта 2010

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

И, помечая его как постоянный, проясняет ваши намерения.

2 голосов
/ 28 марта 2010

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

const double PI = 3.14159;

Он также ускоряет вычисления по сравнению с переменными, вставляя значения во время компиляции и не выводясь из регистра / ячейки памяти.

2 голосов
/ 28 марта 2010

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

1 голос
/ 28 марта 2010

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

Но константы в C # (а скорее в .net) имеют очень различную семантику (с точки зрения реализации) по сравнению собычные переменные.

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

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

1 голос
/ 28 марта 2010

Строго говоря, «const» не требуется. Python, например, не имеет ни «const», ни «private»; Вы указываете свое намерение с соглашением об именах THIS_IS_A_CONSTANT и _this_is_private.

C #, однако, имеет философию проектирования, позволяющую отлавливать ошибки во время компиляции, а не во время выполнения.

1 голос
/ 28 марта 2010

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

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

1 голос
/ 28 марта 2010

По нескольким причинам:

  1. Вы хотите отличить определенные значения, которые имеют определенное значение, от других переменных.
  2. Позже вы можете забыть, что вы не должны изменять значение и вызывать непредвиденное поведение.
  3. Ваш код могут использовать другие люди, и они могут изменить его (особенно если вы разрабатываете библиотеку или API).
  4. Поскольку каждая вещь, которая может пойти не так, как правило, будет - поэтому предотвратите это, сделав такие ошибки обнаруживаемыми во время компиляции, а не во время выполнения.
...