2009-08-14 2 views
8

Мне было интересно, имеет ли тип структуры перечисления предел для своих членов. У меня есть очень большой список «переменных», которые мне нужно хранить внутри перечисления или как константы в классе, но я, наконец, решил сохранить их внутри класса, однако мне немного интересно узнать о пределе членов перечисления (если есть).У enums есть лимит членов на C#?

Итак, у enums есть ограничение на .Net?

+0

Мне просто интересно, что вы делаете, что потребуется столько констант, чтобы задать этот вопрос ... – NotDan

+0

Ну, конечно, я не буду использовать ограничение размера 2^32, но мне нужно много «хранилища», , Мы разрабатываем приложение, которое связано с страхованием, поэтому существует множество переменных, которые должны быть там, чтобы сделать рейтинг, чтобы получить премию, и, как вы можете себе представить, это много (возможно, от 600 до 1000). –

ответ

16

Да. Количество членов с определенными значениями ограничено базовым типом enum - по умолчанию это Int32, поэтому вы можете получить столько разных членов (2^32 - мне сложно, что вы достигнете этого предела), но вы можете явно указать базовый тип, как это:

enum Foo : byte { /* can have at most 256 members with distinct values */ } 

конечно, вы можете иметь столько членов, сколько вы хотите, если все они имеют одинаковое значение:

enum { A, B = A, C = A, ... } 

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

+0

Спасибо, я не знал, что вы можете объявить базовый тип перечисления. –

7

Из-за ограничения в формате PE-файла вы, вероятно, не можете превышать 100 000 000 значений. Может быть, больше, а может и меньше, но определенно не проблема.

+0

Очень хорошая точка зрения. –

6

Из C# Language Specification 3.0, 1.10:

типа ENUM в формат хранения и диапазон возможных значений определяется его базового типа.

В то время как я не 100% уверен, что я бы ожидать, Microsoft C# компилятор только позволяющий неотрицательные значения перечислений, поэтому, если базовый тип является Int32 (это по умолчанию), то я бы ожидать около 2^31 возможные значения, но это деталь реализации, поскольку она не указана. Если вам нужно больше этого, вы, вероятно, делаете что-то неправильно.

+1

Отрицательные числа разрешены до тех пор, пока вы явно не укажете неподписанный базовый тип: Invalid = -1, None = 0, OptionA = 1, ... –

1

Вы можете теоретически использовать int64 в качестве базового типа в перечислении и получить 2^63 возможных записей. Другие дали вам отличные ответы на это.

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

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

Enums отлично подходит для многих вещей. Они чистые, быстрые и простые в реализации. Они отлично работают с IntelliSense и облегчают работу следующего программиста, особенно если имена ясны, кратки и при необходимости документированы.

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

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

enum InsuranceClass 
    { 
    Home,  //value = 0 (int32) 
    Vehicle, //value = 1 (int32) 
    Life,  //value = 2 (int32) 
    Health //value = 3 (int32) 
    } 

В этом примере значение InsuranceClass.Life бы получить сохранялось как номер 2.

Если другой программист делает небольшие изменения в систему и добавляет Pet в перечислении, как это;

enum InsuranceClass 
    { 
    Home,  //value = 0 (int32) 
    Vehicle, //value = 1 (int32) 
    Pet,  //value = 2 (int32) 
    Life,  //value = 3 (int32) 
    Health //value = 4 (int32) 
    } 

Все данные, поступающие из памяти теперь будет показать Life политику как Pet политики. Это очень простая ошибка в создании и может вводить ошибки, которые трудно отследить.

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

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

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

Вот мои грубые правила большого пальца для использования перечислений;

  1. Используйте их для классификации и определения других данных, но не как данные . Чтобы быть яснее, я использовал бы InsuranceClass.Life для , чтобы определить, как должны использоваться другие данные в классе, но я бы не делал базовое значение {pseudocode} InsuranceClass.Life = $653.00 и использовать само значение в вычислениях. Перечисления не являются константами. Выполнение создает путаницу.
  2. Используйте перечисления, когда список перечислений вряд ли изменится. Перечисления велики для фундаментальных концепций, но для постоянно меняющихся идей мало. Когда вы создаете перечисление, это контракт с будущими программистами , которые вы хотите избежать.
  3. Если вы должны изменить перечисление, тогда у вас есть правило, которое следует за тем, что вы добавляете в конец, а не в середину. Альтернативой является то, что вы определяют конкретные значения для каждого перечисления и никогда не меняете их. Точка состоит в том, что вы вряд ли узнаете, как другие используют ваши нулевые значения, и их изменение может нанести ущерб никому , используя код. Это на порядок важнее для любой системы, которая сохраняет данные.
  4. Следствие № 2 и № 3 состоит в том, чтобы никогда не удалять член перечисления. Существуют определенные круги ада для программистов, которые делают это в кодовой базе, используемой другими.

Надеемся, что это расширенный ответ на полезные вопросы.

Смежные вопросы