2010-10-12 3 views
7

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

В следующем примере кода разобьет:

static void Main(string[] args) 
{ 
    int i32 = 10; 
    object obj = i32; 
    long i64 = (long)obj; 
} 

Это приведет к InvalidCastException. Почему это не работает? Является ли C# недостаточно умным, чтобы знать, что объект действительно имеет тип int?

У меня уже есть обходное решение, но мне любопытно, почему приведенный выше образец кода не работал в первую очередь.

Спасибо, Tim

+1

Я отмечаю, что это дубликат многих предыдущих вопросов, в том числе совсем недавно http://stackoverflow.com/questions/3911293 –

ответ

9

Там нет литых доступны из коробочной Int32 на Int64. Создание промежуточного бросание к int должен работать, потому что компилятор готов генерировать это:

// verify obj is a boxed int, unbox it, and perform the *statically* 
// known steps necessary to convert an int to a long 
long i64 = (long) ((int)obj); 

, но не (гипотетически) это:

// Find out what type obj *actually* is at run-time and perform 
// the-known-only-at-run-time steps necessary to produce 
// a long from it, involving *type-specific* IL instructions 
long i64 = (long)obj; 

Вот blog post Эрика Липпертом об этом.

1

Вы имеете в виду компилятор или время выполнения?

Время работы достаточно умное, поэтому оно выбрасывает InvalidCastException. Компилятор, однако, не может точно знать, какой тип вашего объекта, так как вы ввели ваш int.

Виды и типы разрешений бокса и unboxing , которые рассматриваются как объекты. Бокс a тип значения упаковывает его внутри экземпляра объекта Reference .

Так как его в коробке как объект, компилятор не будет жаловаться на это.

Посмотреть более подробную информацию о боксе и распаковка здесь:

http://msdn.microsoft.com/en-us/library/yz2be5wk%28VS.80%29.aspx

3

ЗАКАНЧИВАТЬ this blog post Эрика Липпертом для окровавленных деталей.

Суть его в том, что компилятор будет очень медленным, чтобы выяснить (с помощью проб и ошибок, поскольку object может быть вообще чем угодно), какой тип был помещен в бокс, и можно ли его безопасно отличить.