Когда выбрать struct, а когда class
Вопрос
Как вы решаете, сделать тип структурой или классом? Приведите примеры.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Struct для маленьких неизменяемых значений без идентичности (точка, деньги, диапазон)
Размер: ориентир до 16-24 байт, иначе дорого копировать
Struct не должен часто упаковываться (интерфейсы, object, не-generic коллекции)
Изменяемые структуры опасны: защитные копии, изменения копии вместо оригинала
Class для сущностей с идентичностью, наследованием, большим или разделяемым состоянием
readonly struct и record struct как современный способ сделать значение
Что могут спросить следом
- Почему изменяемая структура в List<T> не меняется через
list[0].X = 1? - Что такое defensive copy и как её избежать?
- Где будет лежать структура, если она поле класса?
Разбор
Я начинаю с семантики: есть ли у объекта идентичность. Заказ, пользователь, соединение: это сущности, их делаю классами. Координата, сумма денег с валютой, диапазон дат: это значения, у них нет «того самого» экземпляра, два одинаковых значения взаимозаменяемы. Такие кандидаты в структуры.
Дальше смотрю на размер и использование. Структура копируется при каждом присваивании и передаче, поэтому она должна быть маленькой, примерно до 16-24 байт. И её не должны постоянно упаковывать: если тип будут класть в object или вызывать через интерфейс, выгода пропадает.
Структуры делаю неизменяемыми: readonly struct или readonly record struct. Изменяемые структуры коварны: list[0].X = 1 не компилируется, потому что индексатор возвращает копию, а у readonly-полей компилятор вызывает методы на защитной копии. Для всего остального, особенно с наследованием и разделяемым состоянием, беру класс.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Типы значений и ссылочные»
- Что такое boxing и unboxing
- Сравнение двух упакованных чисел через ==
- Когда происходит упаковка
- Переприсваивание параметра-класса
- default и конструктор структуры без параметров
- Число различных точек
- Сумма int с переполнением, как в unchecked
- Среднее с пропусками (int?)