Ключевое отличие структур (value types) от классов (reference types) в C# лежит в их поведении при создании и копировании:
// Такой конструктор запрещен в структурах
public struct Point
{
public int X;
public int Y;
// Ошибка компиляции: нельзя определять конструктор без параметров
public Point()
{
X = 0;
Y = 0;
}
}
Особенности выделения памяти:
default(T) семантика:
default(Point)
должно работать без вызова конструктораpublic struct Point
{
public int X;
public int Y;
public Point(int x, int y)
{
X = x;
Y = y;
}
}
public readonly struct ImmutablePoint
{
public int X { get; }
public int Y { get; }
public ImmutablePoint(int x = 0, int y = 0)
{
X = x;
Y = y;
}
}
public struct Point
{
public int X;
public int Y;
public static Point CreateDefault() => new Point { X = 0, Y = 0 };
}
Начиная с C# 10, появилась ограниченная поддержка конструкторов без параметров в структурах, но с важными оговорками:
default(T)
и массивами// Только в C# 10+ с определенными условиями
public struct Point
{
public int X;
public int Y;
public Point()
{
X = 0;
Y = 0;
}
}
Point[] points = new Point[100]; // Все равно будет zero-initialized
T Create<T>() where T : new() => new T();
// Для структур вызовет конструктор по умолчанию только если он явно определен
отсутствие конструкторов по умолчанию в структурах — это осознанное проектное решение, продиктованное требованиями производительности, семантикой типов значений и ограничениями CLR. Современные версии C# добавляют ограниченную поддержку, но основное поведение остается для сохранения обратной совместимости и эффективности.