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 параметры).