#c_sharp #net
Чтобы не вдаваться в детали самого кода, приведу более абстрактную ситуацию. Как мы все прекрасно знаем, следующий код вполне себе рабочий: int a = 1; double b = (double)a; Рабочим он оставался и в таком случае: int a = 1; object b = a; double c = (double)b; (Ибо в объекте содержится int, a int к double приводится без проблем). Но каково же было моё удивление, когда аналогичный по сути кусок кода отказался работать на новом фреймворке. То есть на, грубо говоря, строке double c = (double)b; У меня вылетает ошибка, что такое приведение является недопустимым. Такое положение дел меня весьма расстроило и я, с грустным лицом временно запилив в ту строку Convert.ChangeType(), пошёл писать сюда сей вопрос дабы выяснить, что тут происходит. Является ли данное "ужесточение" типизации не багом, а фичей, и лечится ли это как-нибудь более элегантно, нежели через вызов дополнительного метода из Convert?
Ответы
Ответ 1
Понятно, что упаковка и распаковка/копирование снижают производитель- ность приложения (в плане как замедления, так и расходования дополнительной памяти), поэтому нужно знать, когда компилятор сам создает код для выполнения этих операций, и стараться свести их к минимуму. При распаковке упакованного значимого типа происходит следующее. Если переменная, содержащая ссылку на упакованный значимый тип, равна null, генерируется исключение NullReferenceException. Если ссылка указывает на объект, не являющийся упакованным значением требуемого значимого типа, генерируется исключение InvalidCastException1 Из Рихтера "CLR VIA 4.5"Ответ 2
Не знаю, насколько это более элегантно, но: int a = 1; object b = a; double c = (int)b; Какой тип упаковали, в тот и распаковываете. Эквивалентно double c = (double)(int)b; но приведение к double неявное. Суть в том, что вы должны знать, какой тип вы упаковали в object. Если не знаете какой тип, то можно проверить int a = 1; object b = a; double c; if (b is int) c = (int)b; else throw new ArgumentException();
Комментариев нет:
Отправить комментарий