Если у вас есть перечисление в вашем приложении, и у вас есть только несколько элементов, должны ли вы сделать базовый тип наименьшим возможным типом?
enum smaller : byte
{
one,
two,
three
};
Если у вас есть перечисление в вашем приложении, и у вас есть только несколько элементов, должны ли вы сделать базовый тип наименьшим возможным типом?
enum smaller : byte
{
one,
two,
three
};
Нет. Не оптимизируйте преждевременно, если вы не доказали с помощью профилировщика, что это действительно проблема.
int
— 32 бита, byte
— 8 бит.
- person 0b101010; 16.03.2015
int
на меньшее byte
. Спецификация C# явно указывает, что базовый тип перечисления должен быть byte
, sbyte
, short
, ushort
, int
, uint
, long
или ulong
. Я думаю, вы можете неправильно понять, как работают перечисления.
- person 0b101010; 17.03.2015
Enum.IsDefined
, соответствовал типу перечисления. в противном случае метод выдает исключение. так как я разбирал файл, я изменил тип перечисления на short
вместо приведения параметра к int
- person M.kazem Akhgary; 11.01.2017
Что касается передового опыта:
Если у вас нет особой причины для того, чтобы сделать перечисление типом байта, вы должны оставить его по умолчанию.
Каждый раз, когда вы используете перечисление в операторе switch, у вас должно быть предложение «по умолчанию» для недопустимого значения перечисления. Так что не имеет значения, проверяете ли вы 256-NumRealEnumValues или 2^32-NumRealEnumValues. Оба будут иметь предложение по умолчанию, которое обрабатывает все недопустимые случаи.
Одной из причин явной установки типа перечисления является то, что вы хотите, чтобы ваше перечисление соответствовало другому типу в вашей программе, и вам нужно явно выполнять приведение типов между ними.
Изменение типа на наименьший размер также не поможет вам в решении проблем с версиями. Если у вас точно не указан максимальный размер перечисления. Под проблемами управления версиями я подразумеваю, когда у вас есть скомпилированная dll с использованием перечисления, затем вы добавляете новое значение перечисления, может выполняться некоторый код, который не должен был идти в предложении «по умолчанию» оператора switch.
Об эффективности:
Нет никакой выгоды с точки зрения эффективности, чтобы сделать его байтом.
int более эффективно использовать, потому что процессор на x86 имеет 32-битные регистры. Копирование в регистр выполняется по 32 бита за раз.
Когда вы используете меньший тип, вы должны обнулить часть регистра и скопировать в остальные младшие биты регистра.
Единственная причина сделать это, если вы сохраняете или передаете это значение, используя определенный протокол, который требует, чтобы поле было такого размера.
Если вы сопоставляете модель с перечислением с другой моделью или сериализуете ее, или ваше перечисление отражается в столбце базы данных — тогда я бы посоветовал вам указать тип явно.
Сценарий: у вас есть столбец в базе данных: status_id
с типом tinyint
. И у вас есть enum в вашем коде: enum Status { Well = 1, Bad = 2 }
. И вы используете это перечисление в какой-то сущности. Допустим, вы используете фреймворки сущностей ядра 2.0. Если вы попытаетесь прочитать/записать этот объект из базы данных, вы получите сообщение об ошибке «Невозможно преобразовать объект», если только вы явно не укажете тип byte
.
Что бы получить? Вы сэкономите колоссальные 3 байта памяти за счет немного более медленного выполнения и менее интуитивно понятного или читаемого кода. (Читая это, я должен задаться вопросом, действительно ли у вас была причина для того, чтобы сделать его байтом, и какова могла быть эта причина. Предположительно, вы старались изо всех сил использовать нестандартный тип по какой-то причине).
Если вы планируете хранить миллионы таких вещей, то да, экономия нескольких байтов на каждой может окупиться. В противном случае нет.
По той же причине вы обычно не используете byte или short вместо int.
Вы не должны назначать перечислениям определенный целочисленный тип и позволять C# вернуться к стандартному int
1 , но позволить среде .NET определить наилучший размер для перечисления. Как сказал JaredPar, если вы меняете тип данных, вы обязательно должны проверить, действительно ли это помогает.
Дело в том, что 32-битные целые числа естественны для процессоров x86, потому что их можно легко выровнять оптимальным образом.
1 По умолчанию , связанные постоянные значения членов перечисления имеют тип int
В ядре .Net, если вы вызываете Enum.IsDefined, чтобы проверить, существует ли передаваемое значение в перечислении, вы должны убедиться, что типы совпадают.
ArgumentException: Базовый тип Enum и объект должны быть одного типа или объект должен быть строкой.