Приведение Enum к Uint - PullRequest
       13

Приведение Enum к Uint

6 голосов
/ 06 декабря 2009

Я пишу функцию, которая принимает Enum и приводит к uint. Из того, что я видел при приведении к int, вы должны сначала привести его к объекту: (int) (object) myEnumValue. Если вы напишите (int) myEnumValue, вы получите исключение времени компиляции.

Теперь, когда я попытался привести его к уинтам, я ожидал, что (uint) (object) myEnumValue будет в порядке. Он хорошо компилируется, но при запуске генерирует InvalidCastException. Чтобы заставить его работать, я использовал

(uint) (int) (object) myEnumValue

Я думаю, это выглядит забавно, поэтому я вполне счастлив, но почему это так?

Возможно, было бы правильнее спросить, почему невозможно привести object к uint, но меня интересует, есть ли другой способ перейти от Enum к uint. Есть ли?

Edit:

Контекст - это функция, примерно такая:

public static uint ToUInt (Enum e)
{
    return (uint) (int) (object) e;
}

Редактировать 2:

Лучшее решение было упомянуто thecoop:

Convert.ToUInt32(e)

Ответы [ 3 ]

13 голосов
/ 06 декабря 2009

Подход (uint) (object) myEnum терпит неудачу, потому что по умолчанию перечисления C # используют int в качестве базового типа, а int - это то, во что они превращаются, когда они упакованы. Синтаксис C # делает вид, что перечисления наследуются от их базового типа (например, enum MyEnum : uint).

Вы должны явно указать компилятору сначала распаковать от object до int, а затем выполнить числовое преобразование из int в uint. (Несмотря на то, что синтаксис один и тот же, распаковка из object в тип значения отличается от преобразования между int и uint.)

5 голосов
/ 06 декабря 2009

Из того, что я видел при приведении к int, сначала нужно привести его к объекту: (int) (object) myEnum. Если вы напишите (int) myEnum, вы получите исключение времени компиляции.

Не правда. Вы можете напрямую привести значение enum к целочисленному типу.

Теперь, когда я попытался привести его к uint, я ожидал, что (uint) (объект) myEnum будет в порядке. Он хорошо компилируется, но при запуске генерирует исключение InvalidCastException. Чтобы заставить его работать, я использовал: (uint) (int) (object) myEnum
Я думаю, что это выглядит смешно, поэтому я вполне счастлив, но почему это так?

Когда вы приводите значение enum к object, оно будет помечено как базовый тип , который по умолчанию равен int. Вы не можете распаковать в штучной упаковке значение любого типа, кроме его фактического типа напрямую. Даже это не удастся:

short s = 10;
object o = s;
int i = (int)o; // throws `InvalidCastException` while `int i = (int)s;` works.
0 голосов
/ 19 декабря 2009

В случае, если вам нужно перейти в противоположном направлении, то есть от базового типа к перечислению определенного типа:

enum MyEnumType { a, b, c };
//...
MyEnumType enum_val = (MyEnumType)Enum.ToObject(typeof(MyEnumType), 2);
Console.WriteLine(enum_val == MyEnumType.c);
// "True"

Я обнаружил, что это необходимо (а не просто приведение типов) при разработке универсальных типов. Поскольку вы не можете использовать предложения 'where' для достаточного ограничения универсального на ваш тип перечисления, компилятор не позволит вам привести к нему числовое значение.

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