Unboxing не создает копию значения. Это правильно?
Я читал Microsoft Class Room Training Materil. Я прочитал следующее
Распаковка
Unboxing - это противоположность боксу. Это явное преобразование ссылочного типа в
тип значения. Unboxing извлекает ссылку на тип значения, содержащийся внутри объекта.
Операция unboxing включает проверку экземпляра объекта для обеспечения того, чтобы объект
instance - значение в коробке заданного типа значения. Затем значение из экземпляра
скопирован в переменную типа значения.
**
Unboxing возвращает указатель на данные внутри объекта в штучной упаковке и не создает копию данных.
**
Я действительно не понимаю строку, которую я выделил. он говорит, что при распаковке объекта с боксами он не создает копию, он просто возвращает указатель. Если это так, то переменная типа значения будет выделена в "Куче" вправо?
Рама
Ответы
Ответ 1
Ну, это правда, но не вся картина.
Само распаковывается только указатель на данные, но вы не можете использовать это для доступа к данным на С#. Когда вы сбросили значение в С#, вы всегда скопируете его где-нибудь.
Пример:
object o = 42; //box
int i = (int)o; //unbox
Unboxing iself получает указатель на значение 42
в объекте o
, тогда значение копируется в переменную i
.
Ответ 2
В дополнение к тому, что сказал Гуффа, вот некоторая дополнительная информация:
-
Операция "unboxing", описанная в тексте, который вы указали , описывает инструкцию unbox
CIL. В стандарте CIL это сказано примерно unbox
:
В отличие от box
, который требуется сделать копию типа значения для использования в объект, unbox
не требуется копировать тип значения из объекта. Обычно он просто вычисляет адрес типа значения, который уже присутствующий внутри коробки объект
-
Конверсии unboxing, которые вы используете в С#, не скомпилированы в unbox
. Они скомпилированы в другую команду под названием unbox.any
:
[...] команда unbox.any
извлекает значение, содержащееся в obj (типа O
). (Это эквивалентно unbox
, за которым следует ldobj
.)
По-английски это означает, что unbox.any
выполняет операцию unboxing (unbox
) - которая нажимает указатель на стек оценки - за ней следует операция копирования (ldobj
), которая преобразует указатель в фактическое значение, содержащееся в типе значения и вместо этого нажимает на стек оценки.
Для полноты, вот описание ldobj
:
Команда ldobj
копирует значение в стек оценки. [...] src - неуправляемый указатель (native int) или управляемый указатель (& Амп;). [...]
[Обоснование: ldobj
может использоваться для передачи тип значения в качестве аргумента. конец Обоснование]
Насколько мне известно, компилятор С# никогда не использует unbox
или ldobj
, он всегда использует unbox.any
для выполнения распаковки и ldind.*
для ссылок на разыменования (например, ref
/out
параметры).