Почему Unboxing Enums дает нечетные результаты?

StackOverflow https://stackoverflow.com/questions/4026374

  •  26-09-2019
  •  | 
  •  

Вопрос

Рассмотрим следующее ::

Object box = 5;
int @int = (int)box;  // int = 5
int? nullableInt = box as int?; // nullableInt = 5;
StringComparison @enum = (StringComparison)box; // enum = OrdinalIgnoreCase
StringComparison? nullableEnum = box as StringComparison?; // nullableEnum = null.

2 вещи ::

  1. Почему я могу несполнить StringComparison? Я думаю, это потому, что это базовый тип Int32 Но я все еще не нахожу это странным.
  2. Почему nullableEnum иметь значение null?

Насколько я понимаю, единственным действительным Unboxing находится из типа стоимости в штучной упаковке, является его типом или к нулевым типом. Если int Можно UNBox to Enum, Тогда почему то же самое не верно для ненужных значений? Точно так же, если вместо 5 я в коробках StringComparison.OrdinalIgnoreCase, было бы так nullableInt будет нулевым, но nullableEnum не может быть.

Это было полезно?

Решение

Строго говоря, я думаю, что это ошибка Реализация деталей время выполнения, поскольку Спект C #

Unboxing к NULLBALE-TYPE дает нулевое значение Nullable-Type, если операнд источника является NULL, или завернутый результат распаковки экземпляра объекта в базовый тип Nullable-типа в противном случае.

То есть, если Unboxing To StringComparison работает, то распакнуйтесь донутымиu003CStringComparison> должен работать тоже. Немного неясно, следует ли работать оба или оба потерпеть неудачу. Спец говорит, что

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

Вы должны решить, является ли коробка INT, считается коробочным значением типа StringComprison, потому что базовый тип StringComparison INT INT. Спецификация говорит, что запрещено неверноеecastexception, если коробка содержит «несовместимый объект». INT - это, безусловно, «совместим» со StringComparison, потому что вы можете безопасно скопировать четыре байта из кучи в вашу переменную StringComprison.

Другие советы

Когда вы бросаете Enum или Integer на объект, он все еще содержит информацию о типе. Так box is StringComparison вернется false. Отказ Но это разрешено отбрасывать любого enum или int ни на какую сторону, так что явный литой (StringComparison)box работает. Это особый случай для перечисления. Nullable<T>, С другой стороны, это просто обычный класс, T не обрабатывается каким-либо определенным образом, когда вы бросаете или проверьте тип. Вот почему этот код бросит исключение.

        StringComparison? nullableEnum = (StringComparison?)nullableInt;

1) Да, основной тип ENUM INT и именно поэтому он работает таким образом. Даже больше. Вы можете выполнить следующее:

enum MyEnum
{
    One = 1,
    Two = 2,
}

int i = 3;
MyEnum myEnum = (MyEnum)i; // This works without exceptions.

2) потому что StringComparison? на самом деле Nullable<StringComparison> который другой тип. И as Оператор проверяет только ли объект того же типа, что указано в качестве оператора.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top