2010-10-13 3 views
9

Хорошо, я должен упускать из виду что-то очень простое, но я потерян.Confused от бокса. Литье от -1 до Int64 throws InvalidCastException

Учитывая это

object val = -1; 
var foo = (Int32)(val); 
var bar = (Int64)(val); 

Бросок к Int64 бросков и InvalidCastException.

Я признаю, что это связано с некоторой странностью с боксом, но я не понимаю рассуждений.

Из того, что я понимаю, в коробке вставляется как Int32 на первой строке.

Затем, когда я пытаюсь использовать как нечто отличное от Int32 InvalidCastException. Я полагаю, это означает, что я пытаюсь удалить unbox val как Int64, когда это на самом деле Int32?

Все еще кажется странным. Не удалось ли сбросить значение, а затем попытаться выполнить бросок?

Нечто подобное (Очевидно, что это ужасно упрощена, может быть, коробочный тип не известен, так что это не возможно?):

object val = -1; 
Int32 unboxed = (Int32)(val); 
var bar = (Int64)(unboxed); 

Кто-то (читай: Эрик Липперт) Школа мне на рассуждения позади это.

UPDATE: Из блога Эрика, что Рид разместил ссылку на это является кратким ответом я искал

»... Это было бы огромное количество кода для генерации, и это было бы очень медленный.Этот код, конечно, настолько велик, что вы хотите поместить его в свой собственный метод и просто сгенерировать его. Вместо этого по умолчанию и всегда генерировать медленный, большой и хрупкий код, мы решили, что unboxing может только отменить точный тип. Если вы хотите вызвать медленный метод, который делает все это, он доступен - вы всегда можете вызвать Convert.ToInt32, который выполняет весь этот анализ во время выполнения для тебя. Мы даем вам выбор между «быстрым и точным» или «медленным и слабым», а разумным дефолтом является первое. Если вы хотите, чтобы последний затем вызывал метод ... »

+0

Это что-то. чрезвычайно не-сима PLE. Он путешествует очень много людей ... –

+0

Рид прав; это спрашивается несколько раз в неделю на SO. Вчера его попросили дважды. –

+0

Итак, я явно хромаю, задавая тот же вопрос, что все остальные спрашивают и не ищут сначала. Мне интересно, что это все равно получает 6 голосов, если это такой общий вопрос. По-видимому, поведение по умолчанию - это не самое очевидное поведение. –

ответ

15

Это связано с тем, что вы не можете распаковать и выполнить преобразование за одну операцию. Вы должны удалить значение Int32 в Int32, а затем преобразовать . его тип

из-за этого, это требует объект, который будет Unboxed, затем преобразуется в Int64:

object val = -1; 
int foo = (Int32)val; 
Int64 bar = (Int64)(Int32)val; 

Эрик Липперт покрыты это в деталях на своем блоге под названием Representation and Identity

+0

Удивительный, Эрик Липперт по прокси :) Вы рок –

+0

Другой способ написать: 'Int64 a = -1; объект o = a; Int64 b = (Int64) o; 'Спасибо, Рид! – Nayan

+0

Могут ли люди перестать произносить * приведение *, когда они означают * преобразование *? Не существует «литья» между целыми типами; они * преобразуются *.(К сожалению, C# использует тот же синтаксис для обоих.) – Timwi

 Смежные вопросы

  • Нет связанных вопросов^_^