Имеют ли публичные константы «плохие»?


39

Это:

public MyClass
{
    public const string SomeString = "SomeValue";
}

хуже чем это:

public MyClass
{
    public static string SomeString { get{ return "SomeValue";}}
}

На оба можно ссылаться одинаково:

if (someString == MyClass.SomeString)
     ...

Второй, однако, имеет защиту как собственность. Но действительно ли это лучше, чем const?

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

Любые идеи?


1
Публичные константы, используемые таким образом, просто хороши. Использование свойств таким способом излишне.
Бернард

2
Вы рассматривали возможность использования ключевого слова только для чтения ? ReadOnly дает вам чистый синтанкс const без проблем, упомянутых во многих постах.
Мэтт Раффель

Может также сделать ... public static readonly type constantName = 0;
Снуп

Ответы:


57

В C # это очень плохо по ни одной из причин, упомянутых в этой теме.

Публичные константы в C # запекаются в ссылочных сборках. Это означает, что если у вас есть SomeOtherClass в отдельной сборке, ссылающейся на SomeString в MyClass, CIL, сгенерированный для SomeOtherClass, будет содержать жестко закодированную строку SomeValue.

Если вы собираетесь повторно развернуть dll, которая содержит MyClass, но не SomeOtherClass, и измените const, SomeOtherClass не будет содержать того, что, как вы думаете, будет, - он будет содержать исходное значение.

Если вы на 100% уверены, что это универсальная константа, как Пи, сходите с ума; в противном случае действуйте осторожно.

Вот лучшее объяснение: https://stackoverflow.com/questions/55984/what-is-the-difference-between-const-and-readonly


3
@Oded, но такая же разница между constсвойством только для чтения. constзапекается в вызывающей сборке, свойство только для чтения - нет.
свик

1
Это то, чего я не знал. Это еще одно доказательство того, что публичные поля плохие. Я думаю, что даже «безопасный» пример Pi - плохая идея (а как насчет того, когда разработчик хочет более или менее точных цифр в Pi? И вносит изменения в сборку, не зная этой проблемы.) У меня более 40 сборок в моем решение, и я мог видеть это действительно кусает нас, если мы не будем осторожны.
Vaccano

2
Это «Копирование» происходит в других частях C #? (т.е. перечисления)
Vaccano

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

1
Это одна из главных причин, почему constв C # онемел. Нам нужна лучшая поддержка для неизменяемых ...
KChaloux

22

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

К тому же:

  • Есть более детальный контроль доступа со свойствами. Нужно ли, чтобы он был общедоступным, но на самом деле нужен только защищенный доступ? Нет проблем (по крайней мере, начиная с C # 2).
  • Хотите взломать отладчик при изменении значения? Просто добавьте точку останова в сеттер.
  • Хотите войти все доступ? Просто добавьте запись в геттер.
  • Свойства используются для привязки данных; поля нет.

http://csharpindepth.com/articles/chapter8/propertiesmatter.aspx

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


11

Опасность открытых полей заключается в том, что они изменчивы и что реализация, лежащая в их основе, может быть изменена.

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


1

Константа это данные. Свойства подразумевают возможность поведения, когда вы столько «смотрите» на значение.

Поведение объединения (или будущая возможность этого) с постоянными данными совершенно неверно. Для большинства систем это не имеет большого значения, но может.

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

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

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

Истинные постоянные данные не нуждаются или не хотят инкапсуляции.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.