Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам

>
>
>
Упаковка и распаковка в C#

Упаковка и распаковка в C#

21 Авг 2023

Упаковка (boxing) и распаковка (unboxing) — операции преобразования значимых типов данных в ссылочные и обратно. Эти операции могут негативно сказываться на производительности из-за дополнительных вычислений: выделения памяти под новый объект и копирования данных.

Упаковка (boxing)

Упаковка происходит при преобразовании значимого типа в тип System.Object, System.Enum, System.ValueType или интерфейса. Эта операция может быть выполнена явно и неявно:

int a = 10;
object b = a;          // Неявная упаковка
object c = (object)a;  // Явная упаковка

Неявная упаковка происходит, когда переменная значимого типа используется в контексте, где ожидается ссылочный тип. Примеры таких операций:

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

Несколько примеров рассмотрены подробнее ниже.

Пример 1

struct Point : IComparable<Point>
{
  .... 
  public int CompareTo(Point point) { .... }
}

static void 
ProcessComparableItems<T>(IComparable<T> lhs,
                          IComparable<T> rhs)
{ .... }

static int Calculate(....)
{
  var firstPoint = new Point(....);
  var secondPoint = new Point(....);
  ProcessComparableItems(firstPoint, secondPoint);
  ....
}

Метод ProcessComparableItems работает с двумя параметрами типа IComparable<T>. В то же время структура Point реализует этот интерфейс. Несмотря на это, при вызове метода ProcessComparableItems с аргументами типа Point каждый из них будет упакован:

// ProcessComparableItems(firstPoint, secondPoint);
IL_0039: ldloc.0
IL_003a: box BoxingTest.Program/Point  // <=
IL_003f: ldloc.1
IL_0040: box BoxingTest.Program/Point  // <=
IL_0045: call void 
  BoxingTest.Program::ProcessComparableItems
    <valuetype BoxingTest.Program/Point>(....)
....

Пример 2

var dateTime = new DateTime(....);
Type typeInfo = dateTime.GetType();

dateTime — переменная значимого типа (DateType). У dateTime вызывается метод GetType, определённый в типе System.Object. Чтобы выполнить такой вызов, объект dateTime придётся упаковать:

// Type typeInfo = dateTime.GetType();
IL_0014: ldloc.0
IL_0015: box [System.Runtime]System.DateTime // <=
IL_001a: call instance class
  [System.Runtime]System.Type
  [System.Runtime]System.Object::GetType()
....

Распаковка (unboxing)

Распаковкой называют преобразование упакованного значения обратно в значимый тип. Операция распаковки имеет свои особенности:

  • распаковка обязана осуществляться в точно такой же тип данных, который был упакован. В случае несоответствия возникнет исключение InvalidCastException;
  • при попытке распаковать нулевую ссылку возникнет исключение NullReferenceException.

Пример

double a = 1;
object b = a;
int c = (int)b;

Из-за несоответствия типов при попытке распаковки переменной возникнет исключение InvalidCastException. Исправленный вариант:

int c = (int)(double)b;

Дополнительные материалы

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form