Поделиться через


Выбор между классом и структурой

Замечание

Это содержимое перепечатывается разрешением Pearson Education, Inc. из руководства по проектированию платформы: соглашения, идиомы и шаблоны для повторно используемых библиотек .NET, 2-го выпуска. Этот выпуск был опубликован в 2008 году, и книга с тех пор была полностью пересмотрена в третьем выпуске. Некоторые сведения на этой странице могут быть устаревшими.

Одно из основных решений по проектированию каждого конструктора платформ заключается в том, следует ли разрабатывать тип как класс (ссылочный тип) или как структуру (тип значения). Хорошее понимание различий в поведении ссылочных типов и типов значений имеет решающее значение при выборе.

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

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

Следующее различие связано с использованием памяти. Типы значений упаковываются при приведении к ссылочному типу или одному из интерфейсов, которые они реализуют. Они распаковываются при приведении к типу значения. Так как боксы — это объекты, выделенные в куче и собираемые мусором, слишком много бокса и распаковки могут негативно повлиять на кучу, сборщик мусора и, в конечном счете, производительность приложения. В отличие от этого, такой бокс не возникает, так как ссылочные типы являются приведение. (Дополнительные сведения см. в разделе Упаковка и Распаковка).

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

Наконец, ссылочные типы передаются по ссылке, а типы значений передаются по значению. Изменения, внесённые в экземпляр ссылочного типа, затрагивают все ссылки, указывающие на данный экземпляр. Экземпляры типов значений копируются при передаче по значению. При изменении экземпляра типа значения он, конечно, не влияет ни на одну из его копий. Так как копии не создаются явным образом пользователем, но неявно создаются при возврате аргументов или возвращаемых значений, типы значений, которые можно изменить, могут быть запутаны для многих пользователей. Поэтому типы значений должны быть неизменяемыми.

Как правило, большинство типов в платформе должны быть классами. Однако существуют некоторые ситуации, в которых характеристики типа значения делают его более подходящим для использования структур.

✔️ Рекомендуется определить структуру вместо класса, если экземпляры типа являются небольшими и обычно кратковременными или обычно внедрены в другие объекты.

❌ Избегайте определения структуры, если тип не имеет всех следующих характеристик:

  • Он логически представляет одно значение, аналогичное примитивным типам (int, doubleи т. д.).

  • Он имеет размер экземпляра менее 16 байтов.

  • Это неизменяемо.

  • Его не придется часто упаковать.

Во всех остальных случаях следует определить типы как классы.

© Часть 2005, 2009 Корпорация Майкрософт. Все права защищены.

Перепечатан с разрешения Pearson Education, Inc. из Руководство по проектированию: Соглашения, идиомы и шаблоны для повторного использования библиотек .NET, 2-е издание Кшиштоф Чвалина и Брэд Абрамс, опубликованное 22 октября 2008 года Addison-Wesley Профессиональный в рамках серии разработки Microsoft Windows.

См. также