Урок 5.5 — Все типы данных
Сводка типов C#: значимые и ссылочные, стек и куча, nullable и var.
Типы данных — это основа любой программы. Понимание, как C# управляет памятью, чем отличается struct от class, и что такое «значимые» и «ссылочные» типы, отличает начинающего программиста от уверенного. В этом уроке мы соберём все знания о типах в одну картину.
Значимые (value) vs ссылочные (reference) типы
Это, пожалуй, самое важное разделение в C#. От него зависит, где и как данные хранятся в памяти, как они передаются в методы, и как происходит сборка мусора.
Значимые типы (Value Types)
Значимые типы хранят значение напрямую. Когда ты присваиваешь одну переменную другой — создаётся копия значения. Они хранятся на стеке (stack) — очень быстрой, но ограниченной по размеру памяти:
int a = 10;
int b = a; // b получает КОПИЮ значения a
b = 20; // меняется только b
Console.WriteLine(a); // 10 — a не изменилось!
Ссылочные типы (Reference Types)
Ссылочные типы хранят ссылку на данные. Сами данные лежат в куче (heap) — более медленной, но практически неограниченной памяти. Когда ты присваиваешь одну переменную другой — копируется ссылка, а данные остаются общими:
int[] arr1 = { 1, 2, 3 };
int[] arr2 = arr1; // arr2 получает ССЫЛКУ на тот же массив
arr2[0] = 999; // меняем через arr2
Console.WriteLine(arr1[0]); // 999 — arr1 тоже изменился!
💡 Это объясняет, почему в методах можно изменить содержимое массива или списка, переданного в качестве параметра — ты работаешь с теми же данными в куче, а не с копией.
Стек (Stack) vs Куча (Heap)
Полная таблица встроенных типов C#
Вот все встроенные (built-in) типы C# и их .NET-эквиваленты:
Struct vs Class
В C# ты можешь создавать свои типы. struct — это значимый тип (value type), class — ссылочный (reference type). Выбор между ними — важное архитектурное решение:
struct Point { public int X; public int Y; }
class Person { public string Name; public int Age; }
Point p1 = new Point { X = 10, Y = 20 };
Point p2 = p1;
p2.X = 100;
Console.WriteLine(p1.X); // 10
Person person1 = new Person { Name = "Анна", Age = 25 };
Person person2 = person1;
person2.Name = "Борис";
Console.WriteLine(person1.Name); // "Борис"
Nullable типы: int?, double?
Значимые типы (int, double, bool, struct) не могут быть null. Но иногда нужно выразить «значения нет». Для этого существуют nullable-типы — с вопросительным знаком:
int? age = null;
double? price = null;
bool? isActive = null;
if (age.HasValue)
Console.WriteLine($"Возраст: {age.Value}");
else
Console.WriteLine("Возраст неизвестен");
// Оператор ?. — безопасный доступ
string? name = null;
int? length = name?.Length; // null (не упадёт!)
// Оператор ?? — значение по умолчанию
int actualAge = age ?? 0;
string displayName = name ?? "Гость";
Явное и неявное преобразование
C# — язык со строгой типизацией. Есть два вида преобразований.
Неявное (implicit)
Безопасное, без потерь:
int a = 100;
double b = a; // int → double
long c = a; // int → long
Явное (explicit)
С потерей данных — оператор приведения (тип):
double pi = 3.14159;
int intPi = (int)pi; // 3
Парсинг строк
int num = int.Parse("42");
if (int.TryParse("42", out int result)) { }
double d = double.Parse("3.14");
string text = 42.ToString();
string price = 1234.5.ToString("C");
Ключевое слово var
var — сокращение для «пусть компилятор сам определит тип». Переменная полностью типизирована, просто тип выводится:
var age = 25; // int
var name = "Анна"; // string
var price = 99.9; // double
var list = new List<int>(); // List<int>
// var x; // ❌ Ошибка! Нужна инициализация
var x = 10;
// x = "hello"; // ❌ x — это int!
Сводная таблица: value vs reference
Проверь себя — вопросы
Вопрос 1
Что выведет: int a = 5; int b = a; b = 10; Console.WriteLine(a);?
Ответ: 5 (int — value type, копируется)
Вопрос 2
Может ли int быть null?
Ответ: Обычно нет. int? — может.
Вопрос 3
Что выведет: double d = 3.14; int i = (int)d; Console.WriteLine(i);?
Ответ: 3 (потеря дробной части при явном приведении)
Вопрос 4
string — это value или reference type?
Ответ: Reference type (ссылочный, в куче). Хотя используется как value во многих сценариях.
Что важно запомнить
int? может быть null. ?? — значение по умолчанию. ?. — безопасный доступ.Тест: 5.5: Все типы данных
3 вопроса