Код для иллюстрирования:
int i = 5;
object obj = i;
byte b = (byte)obj; // X
Когда выполнено, это генерирует Систему. InvalidCastException ("Указанный бросок не допустимо") в строке "X". Выполнение двойного броска работает:
byte b = (byte)(int)obj;
Я думал бы, что необходимо смочь бросить помещенный в коробку интервал (если он имеет значение в диапазоне 0.. 255) к байту. Кто-либо может пролить какой-либо свет на это?
(Это находится в .net 2.0, в случае, если это имеет значение).
Разница в поведении, которую вы видите, - это разница между идентичностью и представлением .
Распаковка - это приведение идентичности и операция сохранения представления . Однако преобразование int
в байт
приводит к изменению представления (поскольку есть потенциальная потеря точности).
Вы получаете InvalidCastException
, когда пытаетесь распаковать int
как байт
, потому что идентификатор упакованного значения не байт
, это int
.Когда вы пишете byte b = (byte) obj
, вы сообщаете среде выполнения, Я знаю, что там есть байт
, но что вы действительно хотите сказать, Я думаю, что то, что там, можно преобразовать в байт
.
Чтобы сделать последнее утверждение, вы сначала должны объявить идентификатор объекта, который является int
. Тогда и только тогда вы можете выполнить преобразование с изменением представления в байт
.
Обратите внимание, что это применимо, даже если целевой тип «больше», то есть Int64
. Все явные преобразования, для которых целевой тип не находится в дереве наследования исходного типа, считаются изменяющими представление. А поскольку все типы являются производными от System.Object
, распаковка по определению не может изменить представление.
MSDN явно говорит , что распаковка в другой тип вызовет InvalidCastException
.
Насколько я понимаю, тип, в который распакована переменная, на самом деле является параметром базовой команды сборки CIL . Это код операции unbox
, который фактически вызывает исключение InvalidCastException
.
InvalidCastException генерируется, если объект не упакован как valType.