Какие знаешь типы данных
В C# все типы данных делятся на две основные категории: значимые (value types) и ссылочные (reference types). Основное отличие между ними заключается в том, где хранится значение переменной: значимые типы хранят данные непосредственно в стеке, а ссылочные — в управляемой куче, а в стеке хранится только ссылка на объект. Однако значимые типы могут храниться и в куче, если они являются полями ссылочного типа: например, класс (ссылочный тип) содержит поле типа int (значимый тип), и это поле будет размещено в куче вместе с объектом класса, а не отдельно в стеке.
Как это работает
Когда вы объявляете переменную значимого типа, компилятор выделяет память в стеке для хранения самого значения. При присваивании такой переменной другой переменной происходит копирование значения. Для ссылочных типов в стеке создается переменная, которая хранит адрес объекта в куче; при присваивании копируется только ссылка, а сам объект остается в куче.
Пример значимого типа:
int a = 10;
int b = a; // копируется значение: b = 10, a = 10
b = 20; // a остается 10Пример ссылочного типа:
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().
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. - Помните про упаковку и копирование: значимые копируются по значению, ссылочные — по ссылке.