Хорошо, я, должно быть, упускаю из виду что-то очень простое, но я потерян.
Учитывая это
object val = -1;
var foo = (Int32)(val);
var bar = (Int64)(val);
Приведение к броскам Int64 и InvalidCastException.
Я понимаю, что это связано с некоторой странностью бокса, но я не понимаю причин.
Насколько я понимаю, val в первой строке упакован как Int32.
Затем, когда я пытаюсь использовать что-то другое, кроме Int32 InvalidCastException. Я полагаю, это означает, что я пытаюсь распаковать val как Int64, хотя на самом деле это Int32?
Все равно кажется странным. Разве приведение не могло распаковать значение, а затем попытаться выполнить приведение?
Что-то вроде (очевидно, это ужасно упрощено, может быть, тип в штучной упаковке неизвестен, поэтому это невозможно?):
object val = -1;
Int32 unboxed = (Int32)(val);
var bar = (Int64)(unboxed);
Кто-то (читай: Эрик Липперт) объяснит мне, что стоит за этим.
ОБНОВЛЕНИЕ: из блога Эрика, на который Рид разместил ссылку, это краткий ответ, который я искал
"...Это будет огромный объем кода для генерации, и он будет очень медленным. Код, конечно, настолько велик, что вы захотите поместить его в собственный метод и просто сгенерировать вызов к нему. . Вместо того, чтобы делать это по умолчанию и всегда генерировать медленный, большой и хрупкий код, вместо этого мы решили, что распаковка может распаковывать только до точного типа. Если вы хотите вызвать медленный метод который делает все это, он доступен — вы всегда можете вызвать Convert.ToInt32, который сделает весь этот анализ во время выполнения для вас Мы даем вам выбор между «быстро и точно» или «медленно и небрежно», и разумным значением по умолчанию является первое. Если вы хотите второе, вызовите метод...."