Почему нет нецелых перечислений? - PullRequest
6 голосов
/ 23 марта 2009

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

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

Кто-то подскажет мне, в чем причина или причина отсутствия этого в C #, очень приятно.

Ответы [ 4 ]

8 голосов
/ 23 марта 2009

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

В перечислении числовое значение обычно является вторичным.

В следующем:

enum Fruit {
  Apple,
  Orange,
  Pear,
  Peach
}

мы описываем только набор именованных констант. Мы говорим, что переменная типа Fruit может принимать одно из этих четырех значений. Каково целочисленное значение каждого из них, на самом деле не имеет значения. Пока я называю их только по имени, не имеет значения, является ли значение, представляющее Apple, 0, 1, 32, -53 или 0,002534f.

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

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

6 голосов
/ 23 марта 2009

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

Например, перечисления идеально подходят для описания ff:

enum Color
{
   Black,
   White,
   Red,
   Yellow,
   Blue,
   //everything else in between
}

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

enum Mood
{
    Happy,
    Giddy,
    Angry,
    Depressed,
    Sad
}

или вкус?

enum Taste
{
    Bitter,
    Salty,
    Sweet,
    Spicy
}

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

Это в отличие от таких вещей, как праздники, которые численно значимы .

4 голосов
/ 23 марта 2009

Только разработчики языка могут сказать вам, почему они не допускают нецелые перечисления, но я могу дать вам наиболее вероятное объяснение.

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

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

Как только вы решили пойти по пути занятий (DateTime), нет никаких причин не идти до конца. Если вы хотите использовать перечисления, вы можете создавать перечисления как последовательные целые числа, начиная с нуля, и иметь массив значений DateTime, используя эти перечисления в качестве индексов.

Но я бы просто имел класс Holiday, который предоставлял весь набор и kaboodle внутри класса: константы, подпрограмма get () для возврата DateTime на основе этих констант и т. Д.

Это дает вам истинную инкапсуляцию и возможность полностью изменить реализацию, не затрагивая интерфейс. Зачем отбрасывать одно из преимуществ ООП?

2 голосов
/ 23 марта 2009

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

Перечисления в моем уме просто для представления различных опций, доступных в конкретном случае; на самом деле не хранить данные.

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

...