A struct is a value type you define yourself — same copy semantics as int, but with your own fields and methods.
struct Vector2
{
public double X, Y;
public Vector2(double x, double y) { X = x; Y = y; }
public double Length() => Math.Sqrt(X * X + Y * Y);
}
Structs are worth reaching for when a type is small, logically immutable, and represents a single value rather than an identity — coordinates, a money amount, an RGB color. Guidance historically published by Microsoft suggests keeping a struct's total size small (a commonly cited rule of thumb is under 16 bytes) because every copy — every assignment, every pass-by-value into a method — duplicates that data. A large struct copied around a hot path can be slower than the reference-type equivalent it was meant to optimize, precisely because "copies the data" stops being cheap once the data is big.
struct BigStruct
{
public double A, B, C, D, E, F, G, H; // 64 bytes — copied in full on every assignment/param pass
}
Structs also cannot be null by default (they're value types — see the nullable value types section), always have an implicit parameterless constructor that zero-initializes every field (even if you define your own constructors, unless you're targeting a version of C# that lets you suppress it), and cannot inherit from another struct or class (though they can implement interfaces).