Share via

Record VS Class in C#

Pip 265 Reputation points
2026-02-26T19:07:25.5566667+00:00

Hi,

I'm using .NET 10 with Visual Studio 2026.

Before you explain the difference between: Record VS Class in C#.

Can you please why we need Record ?

What is the syntax and use cases for it ?

Thanks in advance,

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

0 comments No comments
{count} votes

Answer accepted by question author
  1. Bruce (SqlWork.com) 83,581 Reputation points Volunteer Moderator
    2026-03-01T22:07:45.8466667+00:00

    Besides being lighter weight than a class, There are two main feature of records over class.

    • records can be immutable. This is an important feature for many programming patterns (especially those from functional programming)
    • records can be a value type and allocated on the stack instead of the GC. This can have huge performance advantages.
    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Q&A Assist
    2026-02-26T19:07:43.26+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    Records are needed when a type’s main purpose is to hold data and should behave by value (based on its contents) rather than by reference (based on its identity). They provide concise syntax for immutable data models, value-based equality, easy copying with modifications, and better default ToString output.

    In contrast, classes are general-purpose reference types that use reference equality by default and are typically used for objects with identity and behavior, not just data.

    Why use records

    Use a record instead of a class or struct when:

    1. Value equality is desired
      • Records compare equality by their contents: two record instances are equal if they are the same record type and all their fields/properties are equal.
      • Classes use reference equality by default: two variables are equal only if they reference the same object instance.
      • This is ideal for:
        • Data transfer objects (DTOs)
        • Configuration objects
        • Results returned from services or queries
    2. Immutability is desired
      • Records are primarily intended for immutable data models.
      • Immutability is useful for:
        • Thread safety
        • Using objects as keys in dictionaries or in hash-based collections
        • Functional-style programming where data is not mutated in place
    3. Concise, data-centric code is desired
      • Records synthesize:
        • Value-based Equals / GetHashCode
        • A useful ToString that prints property names and values
        • Support for nondestructive mutation via with expressions
      • This reduces boilerplate compared to hand-writing all of this in a class.

    When not to use records

    Records are not appropriate when:

    • The type represents an entity whose identity is more important than its current field values (for example, ORM entities such as Entity Framework Core entities, which rely on reference equality and mutability).
    • The type must be mutable and its identity should not change when its data changes.

    Basic syntax

    Record class (reference type):

    public record Person
    {
        public string FirstName { get; init; }
        public string LastName  { get; init; }
    }
    

    Positional record class (primary constructor syntax):

    public record Person(string FirstName, string LastName);
    

    Key points for record classes:

    • record or record class declares a reference type.
    • Positional parameters in the primary constructor become public init-only properties.
    • Equality is value-based: two Person instances are equal if FirstName and LastName are equal.
    • ToString() prints something like:
        Person { FirstName = Nancy, LastName = Davolio }
      
    • with expressions support nondestructive mutation:
        var p1 = new Person("Nancy", "Davolio");
        var p2 = p1 with { LastName = "Fuller" }; // p1 unchanged, p2 is a copy with one change
      

    Record struct (value type):

    public record struct Point(int X, int Y);
    

    Key points for record structs:

    • record struct declares a value type.
    • Positional properties are mutable in record struct and immutable in readonly record struct.
    • Compiler synthesizes equality and ToString, and a Deconstruct method for positional record structs.

    How records differ from classes and structs

    Compared to classes:

    1. Primary constructor and positional parameters
      • Records can use positional parameters in a primary constructor to define properties concisely and (for record classes) immutably.
    2. Equality semantics
      • For classes: == and Equals use reference equality by default.
      • For records: == and Equals use value equality (all fields/properties must match, and runtime types must match for record classes).
    3. Nondestructive mutation
      • Records support with expressions to create modified copies without changing the original instance.
    4. ToString behavior
      • Records synthesize a formatted ToString that prints the type name and public property names/values.
      • Classes inherit object.ToString by default and usually need a custom override.
    5. Inheritance rules
      • Record classes can inherit from other record classes, but:
        • A record cannot inherit from a class.
        • A class cannot inherit from a record.
      • Record structs do not support inheritance.

    Example of inheritance with record classes:

    public abstract record Person(string FirstName, string LastName);
    
    public record Teacher(string FirstName, string LastName, int Grade)
        : Person(FirstName, LastName);
    
    public static void Main()
    {
        Person teacher = new Teacher("Nancy", "Davolio", 3);
        Console.WriteLine(teacher);
        // output: Teacher { FirstName = Nancy, LastName = Davolio, Grade = 3 }
    }
    

    Equality in inheritance hierarchies for record classes is based on the runtime type, not just the base type. Two records are equal only if their runtime types and all their properties match.

    Typical use cases

    • API request/response models
    • Configuration objects
    • Value objects in domain-driven design (where identity is defined by values, not by an ID)
    • Immutable snapshots of state
    • Data returned from queries where equality should be based on the data, not the instance

    Summary

    • Use a class when modeling entities with identity, mutable state, or complex behavior.
    • Use a record when modeling data-centric types where value equality, immutability, and concise syntax are desired.

    References:


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.