Бокс / распаковка - только типы значений? Реф.типы - кастинг? - PullRequest
2 голосов
/ 17 января 2011

Из MSDN я прочитал, что бокс / распаковка предназначен для обработки типов value как объектов.Но когда я читаю о ArrayList, он читает, что он также делает бокс.Так что я совершенно сбит с толку, так как ArrayList содержит значения и ссылочные типы как объекты.Также следующее не распаковывает с точки зрения терминологии, это просто приведение?

ArrayList a=new ArrayList();
a.Add(someClass);

someClass x=(someClass)a[0];

Ответы [ 3 ]

8 голосов
/ 17 января 2011

ArrayList выполняет упаковку для типов значений, но не для ссылочных типов.Вернее, сам по себе ArrayList не выполняет бокс, а компилятор.Например:

ArrayList list = new ArrayList();
list.Add(5);

фактически

ArrayList list = new ArrayList();
object boxed = 5; // Perform boxing from value type type
list.Add(boxed);

Ваш пример действительно просто приведение - справочное преобразование, а не распаковка.Значение ссылочного типа не нужно помещать в коробку для хранения в ArrayList - это уже ссылка.

Опять же, это верно для бокса в целом, а не для ArrayList.Бокс - это просто способ использования значения типа значения, когда вы действительно хотите ссылку ... ссылка должна быть на объект, поэтому CLR создает объект для переноса значения типа значения и возвращаетссылка на эту оболочку («ящик», в котором хранится значение).

2 голосов
/ 17 января 2011

Бокс / распаковка - это особенность языка и среды выполнения, а не ArrayList. Грубо говоря, - это преобразование типа значения из / в Object тип , и, поскольку ArrayList принимает Object с, любые передаваемые вами типы значений будут автоматически помечены box Инструкция IL.

Точнее говоря, упаковка / распаковка включает создание или проверку нового объекта и копирование данных типа значения из стека в кучу (или наоборот). Это довольно дорого, и вы хотели бы избежать этого, если это возможно.

В случае ссылочных типов обычно не генерируется боксерский код; любая инструкция unbox, которая работает с ссылочным типом, кроме того, просто игнорируется.

0 голосов
/ 26 января 2011

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

Если тип значения передается в код, который ожидает производную от Object, он будет приведен к соответствующему невидимому ссылочному типу;если объект этого ссылочного типа назначен переменной типа значения, он будет приведен обратно.

Кстати, если бы у меня были мои детекторы, был бы какой-то способ указать что-то отличное от значения по умолчанию.Следует использовать метод приведения, но такой функции не существует.

...