C boxing unboxing что это

BestProg

Упаковка и распаковка. Необходимость (преимущества) применения обобщений. Повышение типовой безопасности с помощью обобщений

Содержание

Поиск на других ресурсах:

1. Понятие упаковки (boxing) и распаковки (unboxing)

Допускается также использовать переменную типа object в правой части оператора присваивания:

Но в этом случае нужно указывать явное приведение типов, как видно из строки

иначе будет ошибка на этапе компиляции.

Если переменная типа object используется в левой части оператора присваивания, то компилятор выполняет так называемую упаковку. Если переменная или значение типа object используется в правой части оператора присваивания, то компилятор выполняет распаковку.

Использование обобщений вместо использования типа object дает следующие преимущества:

В следующих пунктах эти преимущества рассматриваются более подробно.

2.1. Преимущество 1. Отсутствие явного приведения типа

Если используется обобщение, то не нужно выполнять явное приведение типов в операции присваивания как показано на рисунке 1.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Рисунок 1. Отличие в явном приведении к типу int между обобщением и типом object

2.2. Преимущество 2. Обеспечение типовой безопасности в обобщениях

При использовании класса object в качестве типа можно допустить ошибку, которая на этапе компиляции не будет обнаружена. Эта ошибка окажется на этапе выполнения, что неприемлемо.

В случае с классом ObjectClass ошибки на этапе компиляции не возникает. Эта ошибка вызовет исключительную ситуацию на этапе выполнения.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Рисунок 2. Особенности выявления ошибки компилятором для обобщенного и необобщенных класса

2.3. Преимущество 3. Повышение производительности

Использование обобщенных классов дает большую производительность (быстродействие) по сравнению с необобщенными. При присвоении значения типа object другим типам и наоборот, компилятор выполняет упаковку и распаковку (смотрите п. 1). Этот процесс требует больше временных затрат чем использование обобщений. В случае с обобщениями формируется типизированный код с привязкой к конкретному типу, который выполняется быстрее.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Источник

Упаковка-преобразование и распаковка-преобразование (Руководство по программированию на C#)

Упаковка представляет собой процесс преобразования типа значения в тип object или в любой другой тип интерфейса, реализуемый этим типом значения. Когда тип значения упаковывается общеязыковой средой выполнения (CLR), он инкапсулирует значение внутри экземпляра System.Object и сохраняет его в управляемой куче. Операция распаковки извлекает тип значения из объекта. Упаковка является неявной; распаковка является явной. Понятия упаковки и распаковки лежат в основе единой системы типов C#, в которой значение любого типа можно рассматривать как объект.

Затем можно выполнить операцию распаковки объекта o и присвоить его целочисленной переменной i :

Следующий пример иллюстрирует использование упаковки в C#.

Производительность

По сравнению с простыми операциями присваивания операции упаковки и распаковки являются весьма затратными процессами с точки зрения вычислений. При выполнении упаковки типа значения необходимо создать и разместить новый объект. Объем вычислений при выполнении операции распаковки, хотя и в меньшей степени, но тоже весьма значителен. Дополнительные сведения см. в разделе Производительность.

Упаковка

Упаковка используется для хранения типов значений в куче со сбором мусора. Упаковка представляет собой неявное преобразование типа значения в тип object или в любой другой тип интерфейса, реализуемый этим типом значения. При упаковке типа значения в куче выделяется экземпляр объекта и выполняется копирование значения в этот новый объект.

Рассмотрим следующее объявление переменной типа значения.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

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

Пример

Распаковка

Распаковка является явным преобразованием из типа object в тип значения или из типа интерфейса в тип значения, реализующего этот интерфейс. Операция распаковки состоит из следующих действий:

проверка экземпляра объекта на то, что он является упакованным значением заданного типа значения;

копирование значения из экземпляра в переменную типа значения.

В следующем коде показаны операции по упаковке и распаковке.

На рисунке ниже представлен результат выполнения этого кода.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Для успешной распаковки типов значений во время выполнения необходимо, чтобы экземпляр, который распаковывается, был ссылкой на объект, предварительно созданный с помощью упаковки экземпляра этого типа значения. Попытка распаковать null создает исключение NullReferenceException. Попытка распаковать ссылку на несовместимый тип значения создает исключение InvalidCastException.

Пример

При выполнении этой программы выводится следующий результат:

Specified cast is not valid. Error: Incorrect unboxing.

При изменении оператора:

будет выполнено преобразование со следующим результатом:

Спецификация языка C#

Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

Источник

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Что такое упаковка и распаковка?

К примеру, здесь мы имеем следующий пример упаковки:

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

А вот состояние памяти в момент произведения операции:

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Чтобы сохранить значение «123» в виде объекта, в куче создается «упаковка», куда впоследствии и перемещаются данные.

Когда же производится распаковка:

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Вот что происходит с памятью:

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Значение «123» было изъято из упаковки и помещено назад в область стека.

Как вы можете себе представить, сии операции могут быть достаточно ресурсоемкими.

Тема связана со специальностями:

Давайте рассмотрим IL

Когда мы производим подобный анализ производительности, часто бывает полезно заглянуть непосредственно в Intermediate Language (IL).

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Теперь скомпилируем приложение и при помощи утилитки ILSpy посмотрим его код внутри EXE.

Как только EXE-файл будет открыт в ILSpy, пронавигируемся к методу Main, выбрав «IL with C#».

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Это де-факто способ, которым операции упаковки и распаковки представлены в IL.

Когда стоит производить упаковку и распаковку?

Код в примере выше скорее всего вам покажется наивным, и вы можете подумать: «Эй, что за вздор! Я никогда не буду такого делать». Что же, в большинстве случаев это действительно так. Но данные в нашем приложении часто упаковываются и распаковываются, когда мы об этом даже не догадываемся.

Гетерогенные коллекции

К примеру, старая школа до сих пор может похвастаться ArrayList.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Метод добавления элемента здесь, как можно отметить, принимает object-параметр.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Таким образом, и здесь производится наша излюбленная упаковка.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

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

Конкатенация строк

Другой интересный пример в виде конкатенации строк.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Эта операция требует наличия метода String.Concat, который принимает два object-параметра.

Видео курсы по схожей тематике:

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

C# Базовый (ООП) 2021

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

How to C# Углубленный

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Дабы избежать подобных ситуаций, нам достаточно просто немного изменить код, используя на переменной типа int метод ToString (и здесь стоит проигнорировать сообщение ReSharper о том, что операция бессмысленна:) ).

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

И все! Никакой упаковки больше нет.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Производительность

Как мы уже говорили, упаковка и распаковка требуют определенных затрат производительности. В случае с конкатенацией строк, выигрыш от применения ToString весьма незначителен. Именно потому, как я упомянул выше, даже ReSharper не советовал нам делать подобное:

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

В этом случае гораздо лучше сохранить читабельность кода без ToString.

Целесообразность оптимизации появляется, как правило, тогда, когда операции упаковки и распаковки предстоит производить в цикле сотни и тысячи раз. В этом случае время выполнения кода с упаковкой может составлять порядка 150 процентов от времени исполнения кода без нее (вы можете сами создать тестовое приложение и сравнить требуемый промежуток времени).

Упакованные значения могут также требовать больше памяти, чем значения в стеке. Копирование значений в/из стека также требует своих затрат. Согласно MSDN, упаковка может занимать порядка 20 раз больше времени, нежели простое присвоение. В то время как распаковка примерно в 4 раза медленней простого присвоения.

Итак. зачем же тогда вообще нужно использовать упаковку и распаковку?

Упаковка и распаковка настолько распространены, что мы не может избежать их полностью. Мы должны знать принцип их работы, чтобы минимизировать их использование, но к этому нужно подходить разумно. Не тратьте свое время на постоянную оптимизацию кода, частую проверку через IL, чтобы убедиться, дабы ни одна лишняя операция упаковки не была использована. Помните, что чистота и простота чтения кода иногда значительно более важна, нежели незаметное, мельчайшее ускорение работы программы.

Бесплатные вебинары по схожей тематике:

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Работа с Microsoft Word на C#

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Практический опыт миграции с Web API на микросервисную архитектуру (продолжение)

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Подведем итоги

В сегодняшнем уроке мы рассмотрели, что такое упаковка и распаковка, как она представлена в IL-коде, и какое влияние на производительность они имеют. Искренне надеюсь, моя статья сумела прояснить некоторые общие концепции, хотя бы чуть-чуть. 🙂

Источник

Boxing/Unboxing

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что этоЗачем производить boxing?
Зачем нужно значение ValueType размещать на куче? int a =2 ; object obj =a; Ну и зачем так.

Ошибка boxing-преобразования
Хочу проверить код через int SortedLinkedList list1 = new SortedLinkedList (); Ошибка.

Да, об этом читал, но так как только начал изучать, не зная всех тонкостей не знаю стоит ли хорошо изучить или быстренько пройти и переключится на что то другое.

А на счет Enum, тут упаковка/распаковка нужна или просто у меня в примере код похож только?

Решение

Переменная в программировании — это место хранения информации.
В C# есть два вида переменных: ссылочные (reference) и значимые (value).
Переменные значимых типов хранят непосредственно значение, а переменные ссылочных типов хранят ссылку на значение, которое лежит где-то в другом месте.
В качестве аналогии можно привести файл и ярлык на файл: в первом хранятся непосредственно данные (значимый тип), а в ярлыке хранится всего лишь указание места, где хранятся данные — это ссылочный тип.

По ходу написания кода может возникнуть ситуация, когда с переменной значимого типа приходится работать как с переменной ссылочного типа: например, если эту переменную нужно передать в метод, который принимает на вход ссылку, а не значение.
Просто передать переменную не получится, потому что принимающая сторона будет воспринимать ее значение как ссылку: например, если в переменной значимого типа хранится значение «12345», то метод, считающий что ему дали ссылку подумает, что «12345» — это место, в котором нужно искать собственно значение. Ничего хорошего из этого, сами понимаете, не выйдет.
В таких ситуациях и производится запаковка: создается дополнительный объект-обертка, в него помещается значение из переменной, потом создается дополнительная переменная ссылочного типа, которая хранит ссылку на эту обертку, и уже такая переменная передается в метод.
Сами видите — много лишних телодвижений, да плюс сборщик мусора, который следит за памятью, должен этот дополнительный объект потом удалить, когда он уже станет не нужен.

Ну а распаковка — это обратный процесс, когда из переменной ссылочного типа вы извлекаете местоположение непосредственно данных, создаете новую переменную значимого типа и копируете в нее эти данные.

Источник

Какой смысл в boxing/unboxing?

Иногда есть необходимость работать с чем то обобщенным, абстрагироваться от конкретного типа. Например при сериализации в json для отправки данных клиенту, как то так

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

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

Смотрите это как на инструмент, вытекающий из механизма ООП(а точнее наследования) в языке C#.

Вот цитата из довольно развёрнутого ответа на такой же вопрос:
Источник цитаты

Подумайте об этом так. У вас есть переменная o типа object. И теперь у вас есть int, и вы хотите поместить его в o. o является ссылкой на что-то где-то, а int категорически не является ссылкой на что-то где-то (в конце концов, это просто число). Итак, что вы делаете, так это: вы создаете новый object, который может хранить int, а затем вы назначаете ссылку на этот объект на o. Мы называем этот процесс «боксом».

Итак, если вам не нужно иметь унифицированную систему типов (т.е. ссылочные типы и типы значений имеют очень разные представления, и вам не нужен общий способ «представить» эти два), то вы не нужен бокс. Если вам не нужно, чтобы int представляло их базовое значение (т.е. Вместо этого int тоже были ссылочными типами и просто сохраняли ссылку на их базовое значение), вам не нужен бокс.

C boxing unboxing что это. Смотреть фото C boxing unboxing что это. Смотреть картинку C boxing unboxing что это. Картинка про C boxing unboxing что это. Фото C boxing unboxing что это

To have a unified type system and allow value types to have a completely different representation of their underlying data from the way that reference types represent their underlying data (e.g., an int is just a bucket of thirty-two bits which is completely different than a reference type).

Think of it like this. You have a variable «o» of type object. And now you have an int and you want to put it into «o». «o» is a reference to something somewhere, and the int is emphatically not a reference to something somewhere (after all, it’s just a number). So, what you do is this: you make a new object that can store the int and then you assign a reference to that object to «o». We call this process «boxing.»

So, if you don’t care about having a unified type system (i.e., reference types and value types have very different representations and you don’t want a common way to «represent» the two) then you don’t need boxing. If you don’t care about having int represent their underlying value (i.e., instead have int be reference types too and just store a reference to their underlying value) then you don’t need boxing.

Where should I use it.

For example, the old collection type ArrayList only eats objects. That is, it only stores references to somethings that live somewhere. Without boxing you cannot put an int into such a collection. But with boxing, you can.

Now, in the days of generics you don’t really need this and can generally go merrily along without thinking about the issue.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *