← Назад к вопросам
Как хранятся в памяти значимые типы данных в C#?
1.2 Junior🔥 21 комментариев
#Другое
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Хранение значимых типов данных в памяти (C# Value Types)
В C# значимые типы (value types) хранятся в стеке (stack), а не в куче (heap). Это фундаментальное различие между структурами и классами в C#.
Основные значимые типы
// Встроенные значимые типы
int x = 42; // 32-битное целое число
long y = 1000L; // 64-битное целое число
float z = 3.14f; // 32-битное число с плавающей точкой
double pi = 3.14159; // 64-битное число с плавающей точкой
bool flag = true; // 1 байт
char c = 'A'; // 2 байта (Unicode)
decimal price = 99.99m; // 128-битное число
// Структуры (тоже значимые типы)
public struct Point
{
public int X;
public int Y;
}
Point p = new Point { X = 10, Y = 20 };
Размеры в памяти
| Тип | Размер | Местоположение |
|---|---|---|
| byte | 1 байт | Stack |
| int | 4 байта | Stack |
| long | 8 байт | Stack |
| float | 4 байта | Stack |
| double | 8 байт | Stack |
| decimal | 16 байт | Stack |
| bool | 1 байт | Stack |
| char | 2 байта | Stack |
| struct | Зависит | Stack |
Stack vs Heap
public class Person { public int Age; } // Reference type → Heap
public struct Point { public int X, Y; } // Value type → Stack
void Example()
{
int age = 30; // Stack
Person person = new Person { Age = 30 }; // Ссылка в Stack, данные в Heap
Point point = new Point { X = 10, Y = 20 }; // Stack полностью
// Stack (более быстрый доступ):
// age: 30
// person: адрес в Heap
// point: X=10, Y=20
}
Копирование значимых типов
Когда вы присваиваете значимый тип, копируется его значение:
int a = 5;
int b = a; // Копируется значение 5
b = 10;
Console.WriteLine(a); // 5 (не изменился)
Console.WriteLine(b); // 10
// То же с структурами:
Point p1 = new Point { X = 0, Y = 0 };
Point p2 = p1; // Копируется весь Point
p2.X = 100;
Console.WriteLine(p1.X); // 0 (не изменился)
Console.WriteLine(p2.X); // 100
Nullable типы
// Значимые типы не могут быть null по умолчанию
int x = null; // Ошибка!
// Используйте Nullable<T> или T?
int? age = null; // Может быть null
double? salary = 5000.50;
if (age.HasValue)
{
Console.WriteLine(age.Value);
}
// Или
Console.WriteLine(age ?? 0); // 0 если null
Производительность и оптимизация
// Хорошо: небольшие значимые типы
public struct SmallPoint { public int X, Y; } // 8 байт
// Плохо: большие структуры
public struct BigData
{
public int[] array; // Ссылка (плохо)
public double[,] matrix; // Ссылка (плохо)
}
// Лучше использовать классы для больших данных:
public class BigDataClass
{
public int[] array;
public double[,] matrix;
}
Boxing и Unboxing
Когда значимый тип преобразуется в object, происходит boxing (копирование в heap):
int x = 42;
object obj = x; // Boxing: копируется в Heap
int y = (int)obj; // Unboxing: копируется обратно в Stack
// Это дорого! Избегайте в циклах
List<object> list = new List<object>();
for (int i = 0; i < 1000000; i++)
{
list.Add(i); // Boxing 1 миллион раз!
}
// Лучше:
List<int> list = new List<int>(); // Без boxing
Модификаторы параметров
void PassByValue(int x) // Копируется
void PassByRef(ref int x) // Передаётся ссылка на Stack переменную
void PassByOut(out int x) // Output параметр
void PassByIn(in int x) // Read-only ссылка (C# 7.2+)
int age = 30;
PassByValue(age); // Копируется
PassByRef(ref age); // Напрямую модифицируется
Сравнение с классами
Значимые типы (Stack):
- Быстрое выделение
- Быстрый доступ
- Автоматическая очистка (выход из scope)
- Копирование при присваивании
Ссылочные типы (Heap):
- Медленнее выделение
- Требует garbage collection
- Разделение ссылок между переменными
- Не копируются при присваивании
Выбирайте структуры для небольших, неизменяемых данных (Point, Color, DateTime). Для сложных объектов с логикой используйте классы.