Встречается на 38% собеседований по C#

Какие знаешь типы данных

В C# все типы данных делятся на две основные категории: значимые (value types) и ссылочные (reference types). Основное отличие между ними заключается в том, где хранится значение переменной: значимые типы хранят данные непосредственно в стеке, а ссылочные — в управляемой куче, а в стеке хранится только ссылка на объект. Однако значимые типы могут храниться и в куче, если они являются полями ссылочного типа: например, класс (ссылочный тип) содержит поле типа int (значимый тип), и это поле будет размещено в куче вместе с объектом класса, а не отдельно в стеке.

Как это работает

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

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

csharp
int a = 10;
int b = a; // копируется значение: b = 10, a = 10
b = 20;    // a остается 10

Пример ссылочного типа:

csharp
var list1 = new List<int> { 1, 2, 3 };
var list2 = list1; // копируется ссылка, list2 указывает на тот же объект
list2.Add(4);      // list1 тоже содержит 4

Какие типы относятся к каждой категории

К значимым типам относятся:

  • Числовые типы: byte, short, int, long, float, double, decimal
  • Логический тип bool
  • Символьный тип char
  • Структуры (struct), например DateTime, TimeSpan
  • Перечисления (enum)

К ссылочным типам относятся:

  • Классы (class), например string, object, пользовательские классы
  • Интерфейсы (interface)
  • Массивы (int[], string[] и т.д.)
  • Делегаты (delegate)

Строка string — это ссылочный тип, хотя ведет себя как значимый в некоторых операциях (например, при сравнении по значению).

Nullable-типы

Отдельно выделяют nullable-типы — это значимые типы, которые могут принимать значение null. Обозначаются знаком вопроса после типа: int?, bool?. Это полезно для работы с базами данных, где поле может быть не заполнено. Для nullable-типов доступно свойство HasValue и метод GetValueOrDefault().

csharp
int? number = null;
if (number.HasValue)
{
    Console.WriteLine(number.Value);
}
else
{
    Console.WriteLine("Значение не задано");
}

Подводные камни

  • Производительность: значимые типы обычно эффективнее, так как не требуют выделения памяти в куче и сборки мусора. Но копирование больших структур может быть дороже, чем передача ссылки.
  • Упаковка и распаковка: при преобразовании значимого типа в object или интерфейс происходит упаковка (boxing) — значение копируется в кучу. Это снижает производительность, поэтому стоит избегать частых упаковок.
  • Ссылочные типы могут быть null, значимые — нет (кроме nullable). Обращение к null вызывает NullReferenceException.

Коротко

  • Типы делятся на значимые (хранят значение в стеке) и ссылочные (хранят ссылку на объект в куче).
  • Значимые: числа, bool, char, структуры, перечисления. Ссылочные: классы, интерфейсы, массивы, делегаты, string.
  • Nullable-типы (int?) позволяют значимым типам принимать null.
  • Помните про упаковку и копирование: значимые копируются по значению, ссылочные — по ссылке.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы