Почему перечисления требуют явного приведения к типу int? - PullRequest
20 голосов
/ 18 января 2011

Это не приводит к потере данных, так в чем же причина явного приведения перечислений к целым числам?

Разве это не было бы более интуитивно понятно, если бы оно было неявным, например, при использовании метода более высокого уровнянапример:

PerformOperation ( OperationType.Silent type )

, где PerformOperation вызывает упакованный метод C ++, который выглядит так:

_unmanaged_perform_operation ( int operation_type )

Ответы [ 7 ]

44 голосов
/ 18 января 2011

Существует два основных и непоследовательных использования перечислений:

enum Medals
{ Gold, Silver, Bronze }

[Flags]
enum FilePermissionFlags
{
    CanRead = 0x01,
    CanWrite = 0x02,
    CanDelete = 0x04
}

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

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

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

5 голосов
/ 18 января 2011

Поскольку перечисления не должны основываться на int:

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

Так что вы можете сделать что-то вроде этого:

enum Something :long  { valueX = 0, valueY = 2147483648L }
2 голосов
/ 18 января 2011

Не было бы более интуитивно понятно, если бы оно было неявным, скажем, когда у вас есть метод более высокого уровня, такой как:

Я на самом деле так не думаю.В этом случае вы пытаетесь использовать Enum в крайнем случае.

Однако, если перечисления были неявно преобразованы в целочисленные значения, это значительно снизило бы их эффективность.Вызывая int-преобразование явно, компилятор обрабатывает enum как специальный тип - один из многих параметров, а не целое число.Это более четко демонстрирует намерение перечисления и уменьшает вероятность ошибок программиста (то есть: присваивает значения, которые не определены в перечислении, переменной enum и т. Д.).

Лично я рад, что перечислениев C # больше, чем (эффективно) постоянное значение типа int.

2 голосов
/ 18 января 2011

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

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

1 голос
/ 05 апреля 2017

Я думаю, что ответ на вопрос "Почему перечисления требуют явного приведения к типу int?"является то, что строго типизированные перечисления в соответствии с C # являются полезной защитой от распространенных ошибок программирования.

Представьте, что у меня есть приложение для управления рисованием, основанное на двух перечислениях:

enum Textures { Gloss, Satin, Matt };
enum Colors { White, Green, Red, Blue, Brown };

И комната -Метод рисования, подобный следующему:

private void PaintRoom (Textures texture, Colors color)

На языке с сильным типом перечисления, как в C #, такая команда:

 // nonsensical attempt to have texture=White and color=Matt
PaintRoom(Colors.White, Textures.Matt);

... приведет к ошибке во время компиляции (не могу поместить цвет туда, где ожидается текстура и наоборот).Но в языках, где перечисления не являются строго типизированными и / или может происходить неявное преобразование (включая C и C ++), и наши Colors, и наши Textures могут рассматриваться как int, поэтому мы можем с радостью выпуститьPaintRoom(Colors.White, Textures.Matt), и она будет хорошо скомпилирована, но в итоге мы получим комнату, окрашенную красным глянцем (0, 2) вместо матового белого (2, 0), который мы намеревались, и код на быстрый взгляд, кажется, говорит.

Так что строго типизированные перечисления в основном полезны, чтобы не допустить случайного помещения людей в места, для которых они не предназначены.И когда кто-то действительно хочет, чтобы его перечисление было int, C # заставляет кодера прояснить свое намерение, настаивая на явном преобразовании.

1 голос
/ 18 января 2011

Так работает C # ...

Если Enum унаследовал от int, то это должно быть возможно. Enum не наследует от int, и поэтому требуется приведение.

Единственный способ неявного приведения классов - если они наследуются.

0 голосов
/ 30 июля 2014

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

public ValueType State {
    get {
        return state;
    }
    set {
        state = (int)value;
    }
}

и, таким образом, я мог сказать как playerObject.animator.State = Player.STANDING, так и monsterObject.animator.State = Monster.DROOLING неявно, насколько мог бы сказать вызывающий класс.законная причина, почему я должен рассматривать значения перечисления как числа.

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