Ссылочные и значимые типы в C
В C# все типы делятся на две большие категории:
- Значимые типы (Value Types)
- Ссылочные типы (Reference Types)
Что такое значимые типы?
Значимые типы хранят данные непосредственно. Когда ты присваиваешь переменную значимого типа другой переменной — создаётся копия.
Примеры значимых типов:
- Все числа:
int
,float
,double
,decimal
bool
,char
struct
(включаяDateTime
,Guid
)enum
Пример:
int a = 10;
int b = a; // b = 10, копия значения
b = 20;
Console.WriteLine(a); // 10 — значение a не изменилось
````
> ✔️ Значимые типы передаются **по значению (by value)**
> ❗ Используют **стек (stack)** для хранения (в большинстве случаев)
---
## Что такое ссылочные типы?
Ссылочные типы **хранят ссылку на объект**, который находится в **куче (heap)**. При копировании переменной копируется **ссылка**, а не объект.
### Примеры ссылочных типов:
* `string`
* `class`
* `object`
* `interface`
* `delegate`
* массивы: `int[]`, `string[]`
### Пример:
```csharp
class Person {
public string Name;
}
Person p1 = new Person { Name = "Alice" };
Person p2 = p1; // p2 указывает на тот же объект, что и p1
p2.Name = "Bob";
Console.WriteLine(p1.Name); // Bob — изменился оригинальный объект
✔️ Ссылочные типы передаются по ссылке (by reference)
❗ Используют кучу (heap), а ссылка хранится в стеке
Таблица сравнения
Характеристика | Значимые типы | Ссылочные типы |
---|---|---|
Хранение данных | В самом объекте | В объекте — ссылка на данные в куче |
Хранение в памяти | Обычно в стеке | Ссылка в стеке, данные в куче |
Передача | По значению | По ссылке |
Поведение при копии | Создаётся новая копия | Копируется ссылка |
Наследование | Нельзя | Можно |
Null | Нельзя быть null |
Может быть null |
Примеры | int , double , struct |
string , class , array |
struct vs class
Особенность | struct |
class |
---|---|---|
Тип | Значимый | Ссылочный |
Наследование | Нельзя | Можно |
Производительность | Быстрее (меньше аллокаций) | Может быть медленнее |
Где используется | Мелкие объекты (например, Point , Color ) |
Сложные объекты |
⚠️ Из-за копирования, большие
struct
могут приводить к падению производительности.
Nullable-значимые типы
Значимые типы нельзя сделать null
, но можно использовать Nullable<T>
или сокращение ?
.
int? a = null; // можно
bool? flag = true;
Это полезно при работе с БД или данными, где значение может быть отсутствующим.
Передача в методы
Значимый тип:
void ChangeValue(int x) {
x = 100;
}
int a = 5;
ChangeValue(a);
Console.WriteLine(a); // 5 — не изменилось
Ссылочный тип:
void ChangeName(Person p) {
p.Name = "Updated";
}
Person p = new Person { Name = "Original" };
ChangeName(p);
Console.WriteLine(p.Name); // Updated — изменился сам объект
Выводы
Что нужно помнить |
---|
Значимые типы копируют данные |
Ссылочные типы копируют ссылки |
Классы — это ссылочные типы, структуры — значимые |
Значимые типы хранятся обычно в стеке, ссылочные — в куче |
Для nullable значимых типов используй T? или Nullable<T> |
Полезные команды
# Декомпиляция и просмотр типов
dotnet ilspy YourApp.dll
# Запуск простого проекта
dotnet run