Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A record struct is a value type introduced in C# 10 that combines the inline allocation and value semantics of a standard struct with the compiler-synthesized boilerplate of a record. It automatically generates members for strongly-typed value equality, non-destructive mutation, and formatted string representation.

Syntax and Declaration

A record struct can be declared using standard property syntax or positional syntax (primary constructors).
// Positional syntax (Mutable by default)
public record struct Point(double X, double Y);

// Readonly positional syntax (Immutable)
public readonly record struct Vector3(float X, float Y, float Z);

// Standard syntax with explicit property definitions
public record struct User
{
    public string Name { get; init; }
    public int Age { get; set; }
}

Compiler-Synthesized Members

When you declare a record struct, the C# compiler automatically injects the following members into the Intermediate Language (IL):
  • IEquatable<T> Implementation: A strongly-typed Equals(T other) method that performs field-by-field comparison.
  • Object Overrides: Overrides for Object.Equals(object) and Object.GetHashCode().
  • Equality Operators: Overloaded == and != operators.
  • Formatting: A ToString() override that outputs the type name along with the values of all public properties and public fields, supported by a synthesized PrintMembers(StringBuilder) method.
  • Deconstructor: A Deconstruct method (generated only when using positional syntax) allowing tuple-style deconstruction of the positional parameters defined in the primary constructor.

Mutability and Positional Syntax

Unlike a record class, where positional parameters generate init-only properties, a standard record struct with positional parameters generates mutable (get and set) properties. To enforce immutability in a positional record struct, the readonly modifier must be explicitly applied to the declaration.
public record struct MutablePoint(int X, int Y);
// Compiler generates: public int X { get; set; }
// Compiler generates: public int Y { get; set; }

public readonly record struct ImmutablePoint(int X, int Y);
// Compiler generates: public int X { get; init; }
// Compiler generates: public int Y { get; init; }

Non-Destructive Mutation

record struct types support the with expression, which creates a new instance by copying the existing instance’s state and applying specified modifications. Because a record struct is a value type, the with expression utilizes standard struct assignment (a shallow copy) rather than the hidden <Clone>$ method synthesized for record class types. If the record struct contains reference types, the references themselves are copied, not the underlying objects.
public readonly record struct Color(byte R, byte G, byte B);

Color red = new(255, 0, 0);
Color magenta = red with { B = 255 }; 

Equality Semantics

While standard C# struct types inherently possess value equality, their default implementation relies on System.ValueType.Equals(). This base method uses reflection to compare fields, which incurs significant performance overhead and boxing. A record struct bypasses this overhead. The compiler generates a direct, strongly-typed comparison of all instance fields (both backing fields for properties and explicit fields). Two record struct instances are evaluated as equal if they are of the exact same type and all their corresponding fields hold equal values.
Master C# with Deep Grasping Methodology!Learn More