Тип struct в C# — это значимый или ссылочный тип?

Ответ

Тип struct в C# является значимым типом (value type).

Ключевые отличия от ссылочных типов (class):

  1. Место хранения: Экземпляры struct обычно размещаются в стеке (stack) или внутри других объектов, если являются их полями. Экземпляры class размещаются в управляемой куче (heap).
  2. Копирование: При присваивании или передаче struct в метод копируется всё его значение (по умолчанию). Для class копируется только ссылка на объект в куче.
  3. Наследование: struct не может наследовать от другого struct или class (кроме неявного наследования от System.ValueType). Не может быть базовым типом.
  4. Значение по умолчанию: Для struct это экземпляр, где все поля инициализированы своими значениями по умолчанию (например, 0 для int). Для classnull.

Пример, демонстрирующий семантику копирования:

public struct Point
{
    public int X;
    public int Y;
}

Point p1 = new Point { X = 10, Y = 20 };
Point p2 = p1; // Происходит ПОЛНОЕ КОПИРОВАНИЕ значений полей X и Y

p2.X = 100; // Изменяется только копия
Console.WriteLine(p1.X); // Вывод: 10 (оригинал не изменился)
Console.WriteLine(p2.X); // Вывод: 100

Когда использовать struct: Для небольших, неизменяемых (или преимущественно неизменяемых) типов, которые логически представляют единое значение (например, Point, ComplexNumber, Money). Это может повысить производительность за счет уменьшения нагрузки на сборщик мусора и лучшей локализации данных.

Ответ 18+ 🔞

Слушай, вот объясню тебе про эти struct в C# так, чтобы понятно было, как гвоздь в стену. Это же не class, тут всё по-другому, как будто сравниваешь литр водки с бутылкой пива — внешне похоже, а на деле пиздец как различается.

Чем они от классов отличаются, если по-простому:

  1. Где живут: Структура — это как паспорт в кармане. Он у тебя прямо тут, в стеке, под рукой. А класс — это как твоя машина на парковке. Ты в кармане держишь только бумажку с номером парковочного места (ссылку), а сама тачка — в куче, на другом конце двора.
  2. Копирование: Вот это самое важное! Когда ты присваиваешь одну структуру другой или в метод передаёшь — происходит полное, блядь, клонирование. Ксерокс включается и делает точную копию всего содержимого. С классом такого нет — ты просто копируешь бумажку с тем же номером парковки, и оба куска бумаги ведут к одной и той же тачке. Поменял что-то в тачке через одну бумажку — и во второй бумажке изменения видны, потому что тачка-то одна!
  3. Наследование: Со структурами тут полный швах. Они не могут быть родителями и не могут иметь родителей (ну, кроме System.ValueType, но это так, формальность). Они сами по себе, как суровые сибирские мужики.
  4. Значение по умолчанию: Создал структуру, а поля не заполнил? Не беда. Она уже не null, она уже существует! Все её поля будут сброшены в ноль, false или нулл для ссылок. Класс же по умолчанию — это null, то есть пустое место, указатель в никуда.

Смотри, какой наглядный пиздец:

public struct Point
{
    public int X;
    public int Y;
}

Point p1 = new Point { X = 10, Y = 20 };
Point p2 = p1; // ВНИМАНИЕ! Здесь не ссылка скопировалась, а ВЕСЬ ПАСПОРТ, ВСЕ ЦИФРЫ!

p2.X = 100; // Мы исправили цифру в КОПИИ паспорта.
Console.WriteLine(p1.X); // Вывод: 10 (а в оригинальном паспорте всё на месте, ёпта!)
Console.WriteLine(p2.X); // Вывод: 100 (в копии — да, поменяли)

Так когда эту структуру использовать-то? Представь, что у тебя есть координата точки на экране. Это просто два числа, X и Y. Логично их завернуть в один маленький контейнер. Вот для таких мелких, простых штук, которые по смыслу — единое значение (точка, цвет RGB, комплексное число), структура идеальна. Они быстрые, потому что не заставляют сборщик мусора пахать как лошадь, и данные лежат компактно.

Но если твой тип большой, с кучей полей, или он должен меняться в десяти местах одновременно — не выёбывайся, бери class. А то накопируешь эти структуры, и каждая при присваивании будет клонироваться — памяти сожрёшь овердохуища, и производительность в пизду улетит.