Как CLR узнает тип упакованного объекта? - PullRequest
14 голосов
/ 16 апреля 2010

Когда тип значения упакован в рамку, он помещается внутри нетипизированного эталонного объекта. Итак, что вызывает здесь недопустимое исключение приведения?

long l = 1;
object obj = (object)l;
double d = (double)obj;

Ответы [ 3 ]

17 голосов
/ 16 апреля 2010

Нет, он не помещен в нетипизированный объект. Для каждого типа значения в CLR имеется ссылочный тип в штучной упаковке. Таким образом, у вас будет что-то вроде:

public class BoxedInt32 // Not the actual name
{
    private readonly int value;
    public BoxedInt32(int value)
    {
        this.value = value;
    }
}

Этот коробочный тип не доступен напрямую в C #, хотя он есть в C ++ / CLI. Очевидно, что знает оригинальный тип. Таким образом, в C # у вас должен быть тип времени компиляции object для переменной, но это не значит, что это фактический тип объекта.

Подробнее см. ECMA CLI или CLR через C # .

9 голосов
/ 17 апреля 2010
6 голосов
/ 16 апреля 2010

Ответ Джона Скита охватывает причину; Что касается того, как обойти это, вот что вы должны сделать:

long l = 1;
object obj = (object)l;
double d = (double)(long)obj;

Причина двойного применения заключается в следующем; когда .NET распаковывает переменную, он знает только, как распаковать ее в тип, из которого она была упакована (long в вашем примере.) После того, как вы распаковали ее и получили надлежащий long примитив, вы можете затем привести это double или любой другой тип, отлитый из long.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...