Бокс/распаковка - только типы значений? Ref.types - кастинг?

StackOverflow https://stackoverflow.com/questions/4711005

  •  11-10-2019
  •  | 
  •  

Вопрос

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

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

someClass x=(someClass)a[0];
Это было полезно?

Решение

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 создает объект для обертывания значения типа значения, и возвращает ссылку на эту обертку («Box», хранящий значение).

Другие советы

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top