Есть ли опыт работы со структурами (struct) в C#?

«Есть ли опыт работы со структурами (struct) в C#?» — вопрос из категории C# Core, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, опыт работы со структурами (value types) в C# есть. Они являются ключевым инструментом для оптимизации производительности в определённых сценариях.

Ключевые особенности и отличия от классов:

  • Тип значения: Хранятся в стеке (если не упакованы и не являются полями ссылочного типа), что минимизирует нагрузку на сборщик мусора (GC).
  • Копирование по значению: При присваивании или передаче в метод по значению создаётся полная копия данных.
  • Наследование: Не поддерживают наследование (кроме неявного наследования от System.ValueType), но могут реализовывать интерфейсы.
  • Конструктор: Имеют неявный параметрный конструктор, инициализирующий поля нулевыми значениями. Начиная с C# 10, можно определять собственные конструкторы без параметров.

Практический пример — координата точки:

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

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public double DistanceTo(Point other) => 
        Math.Sqrt(Math.Pow(X - other.X, 2) + Math.Pow(Y - other.Y, 2));
}

// Использование:
Point p1 = new(10, 20);
Point p2 = p1; // Создаётся копия значения
// p2.X = 30; // Ошибка компиляции, так как структура readonly

Когда использовать структуры (best practices):

  1. Размер до 16 байт. Большие структуры при частом копировании могут негативно сказаться на производительности.
  2. Неизменяемость (immutable). Рекомендуется делать структуры readonly, чтобы избежать неочевидного поведения при копировании.
  3. Частые аллокации в критичном к производительности коде. Например, в tight loops, где создание множества мелких объектов-классов создало бы давление на GC.

Типичные сценарии: координаты, цвет в формате RGBA, ключи для словарей, небольшие данные для межпроцессного взаимодействия (P/Invoke).