Ответ
Место хранения значимого типа зависит от контекста его объявления, а не от самого типа.
Основные случаи:
| Контекст объявления | Место хранения | Пояснение и пример |
|---|---|---|
| Локальная переменная в методе | Стек (Stack) | Выделяется в стековом фрейме метода и очищается при его завершении. void Method() { int x = 5; } |
Поле класса или ссылочного struct |
Куча (Heap) | Является частью памяти, выделенной для содержащего его объекта. class MyClass { public int Value; } |
Поле значимого struct |
Зависит от контекста родителя | Хранится там же, где и экземпляр struct. Если struct в стеке — поле в стеке, если в куче — поле в куче. |
| Элемент массива | Куча (Heap) | Массивы являются ссылочными типами. int[] arr = new int[10]; // 10 int'ов лежат в куче |
Ключевые концепции:
- Упаковка (Boxing): Когда значимый тип присваивается переменной типа
objectили интерфейса, он копируется в кучу. Это дорогая операция, которой следует избегать.int i = 123; object o = i; // Boxing: значение 'i' копируется в кучу. - Ref struct: Особый вид структур, которые могут находиться только в стеке и не могут быть упакованы (например,
Span<T>,ReadOnlySpan<T>).