Когда тип значения упаковывается, он помещается в невведенном ссылочном объекте. Таким образом, что вызывает недопустимое исключение броска здесь?
long l = 1;
object obj = (object)l;
double d = (double)obj;
Нет, он не помещается в нетипизированный объект. Для каждого типа значения в CLR есть упакованный ссылочный тип. Таким образом, у вас будет что-то вроде:
public class BoxedInt32 // Not the actual name
{
private readonly int value;
public BoxedInt32(int value)
{
this.value = value;
}
}
Этот тип в штучной упаковке недоступен напрямую в C #, хотя он есть в C ++ / CLI. Очевидно, что знает исходный тип. Итак, в C # у вас должен быть тип времени компиляции объекта
для переменной, но это не означает, что это фактический тип объекта.
Дополнительные сведения см. В спецификации CLI ECMA или CLR через C # .
Ответ Джона Скита объясняет, почему; Что касается того, как это обойти, вот что вам нужно сделать:
long l = 1;
object obj = (object)l;
double d = (double)(long)obj;
Причина двойного приведения в следующем; когда .NET распаковывает переменную, она знает только, как распаковать ее в тип, из которого она была упакована ( long
в вашем примере.) После того, как вы распаковали ее, и у вас есть правильный long
, вы можете преобразовать его в double
или любой другой тип, который может быть приведен из long
.
Я отвечаю на ваш вопрос здесь:
http://blogs.msdn.com/ericlippert/archive/2009/03/19/presentation-and -identity.aspx