Master C# Programming From Scratch

Clear, interactive, and structured coding lessons designed for absolute beginners.

Record Types

Record types are a modern C# feature designed for working with data-focused objects. They provide built-in support for value-based equality and make it easier to create immutable data models.

Records are particularly useful when the main purpose of a type is to represent and transfer data rather than contain complex mutable behavior.

Key Idea: A class normally compares objects by reference, while a record can compare objects based on their data values.

Creating a Record

A record can be declared using the record keyword.

C#
public record Student
{
    public int Id { get; init; }

    public string Name { get; init; }

    public string Course { get; init; }
}

The init accessor allows a property to be set during object initialization but prevents normal modification afterward.

Creating a Record Object

C#
using System;

class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Course { get; set; }
}

class Program
{
    static void Main()
    {
        Student student = new Student
        {
            Id = 101,
            Name = "Pradnya",
            Course = "Dot.Net Full Stack"
        };

        Console.WriteLine(student.Name);
        Console.WriteLine(student.Course);
    }
}

Output

Output
Pradnya
Dot.Net Full Stack

Positional Records

C# also provides a shorter syntax called a positional record. Properties are declared directly in the record declaration.

C#
using System;

public record Student(
    int Id,
    string Name,
    string Course
);

class Program
{
    static void Main()
    {
        Student student =
            new Student(101, "Pradnya", "Dot.Net Full Stack");

        Console.WriteLine(student.Id);
        Console.WriteLine(student.Name);
        Console.WriteLine(student.Course);
    }
}

Output

Output
101
Pradnya
Dot.Net Full Stack

Value-Based Equality

One of the important features of records is value-based equality. Two record objects containing the same values are considered equal.

C#
using System;

public record Student(
    int Id,
    string Name
);

class Program
{
    static void Main()
    {
        Student student1 =
            new Student(101, "Rahul");

        Student student2 =
            new Student(101, "Rahul");

        Console.WriteLine(student1 == student2);
    }
}

Output

Output
True
Important: Records compare their data values rather than simply checking whether two variables refer to the same object.

Class vs Record

Feature Class Record
Primary Purpose General-purpose objects Data-focused objects
Equality Reference-based by default Value-based by default
Immutable Style Must be designed manually Supported naturally with init properties
Syntax More verbose Can be concise

with Expression

The with expression creates a new record object based on an existing record while changing one or more values.

C#
using System;

public record Student(
    int Id,
    string Name,
    string Course
);

class Program
{
    static void Main()
    {
        Student student1 =
            new Student(101, "Rahul", "Java");

        Student student2 =
            student1 with
            {
                Course = "C# Full Stack"
            };

        Console.WriteLine(student1.Course);
        Console.WriteLine(student2.Course);
    }
}

Output

Output
Java
C# Full Stack

The original record remains unchanged, while student2 contains the modified value.

ToString() with Records

Records provide a useful generated ToString() implementation that displays the record type and its values.

C#
using System;

public record Student(
    int Id,
    string Name,
    string Course
);

class Program
{
    static void Main()
    {
        Student student =
            new Student(101, "Rahul", "C# Full Stack");

        Console.WriteLine(student);
    }
}

Output

Output
Student { Id = 101, Name = Rahul, Course = C# Full Stack }

Immutability

Records are commonly used with immutable data. Once an object has been initialized, its values can be kept unchanged.

C#
using System;

public record Employee(
    int Id,
    string Name
);

class Program
{
    static void Main()
    {
        Employee employee =
            new Employee(1, "Amit");

        // employee.Name = "Rahul";  // Not allowed

        Console.WriteLine(employee.Name);
    }
}

Output

Output
Amit

Records in ASP.NET Core Web API

Records are useful for DTOs (Data Transfer Objects) in ASP.NET Core applications.

A DTO represents the data that should be transferred between the client and server.

C#
public record StudentDto(
    int Id,
    string Name,
    string Course
);

A controller can return the record as an API response.

C#
[HttpGet]
public IActionResult GetStudent()
{
    StudentDto student =
        new StudentDto(
            101,
            "Rahul",
            "C# Full Stack"
        );

    return Ok(student);
}

JSON Response

JSON
{
  "id": 101,
  "name": "Rahul",
  "course": "C# Full Stack"
}
CIIT Practical Point: Records are especially useful for DTOs, API request models, API response models, configuration-style data, and other situations where the main purpose of a type is to carry data.

Record Class and Record Struct

A record can be a reference type or a value type. record creates a record class, while record struct creates a record value type.

C#
public record class Student(
    int Id,
    string Name
);

public record struct Point(
    int X,
    int Y
);
Type Category
record class Reference type
record struct Value type

When Should You Use Records?

  • When the type mainly represents data.
  • When value-based equality is useful.
  • When immutable data is preferred.
  • When creating DTOs for Web APIs.
  • When concise data model syntax improves readability.

When Should You Prefer a Class?

  • When the object has significant mutable state.
  • When identity is more important than value equality.
  • When the type represents a complex domain entity.
  • When object behavior is the primary focus.

Common Mistakes

  1. Assuming records are completely immutable in every possible design.
  2. Using records for every class in an application.
  3. Confusing value equality with reference identity.
  4. Modifying data directly when immutable design is intended.
  5. Using a record where entity identity and lifecycle are more important.

Best Practices

  • Use records primarily for data-oriented types.
  • Prefer immutable properties when appropriate.
  • Use records for DTOs where value semantics are useful.
  • Use with expressions when creating modified copies of records.
  • Choose classes when object identity and mutable behavior are central to the design.

Interview Questions

1. What is a record in C#?

A record is a data-oriented type that provides value-based equality and convenient syntax for immutable-style objects.

2. What is the main difference between a class and a record?

A class uses reference-based equality by default, while a record provides value-based equality.

3. What is a positional record?

A positional record is a concise record declaration in which its primary data properties are declared directly in the record header.

4. What is the with expression?

The with expression creates a new record based on an existing record while allowing selected values to be changed.

5. What is value-based equality?

Value-based equality means objects are considered equal when their relevant data values are equal.

6. What is a record struct?

A record struct is a value-type record that combines record-style value equality with struct semantics.

7. Why are records useful in ASP.NET Core?

Records are useful for representing DTOs and other data-transfer models where value-based semantics and concise immutable-style definitions are beneficial.

Practice Programs

  1. Create a Student positional record.
  2. Create two records with the same values and compare them.
  3. Create a new record using the with expression.
  4. Create an Employee record with Id, Name, and Department.
  5. Create a Product record and display it using ToString().
  6. Create a record DTO and return it from an ASP.NET Core Web API controller.
  7. Create a record struct representing a Point with X and Y.

Summary

Record types are designed for data-focused objects and provide value-based equality by default.

You learned standard records, positional records, value-based equality, immutable-style properties, with expressions, and generated ToString() behavior.

You also learned the difference between record class and record struct.

Records are especially useful for DTOs and data-transfer models in modern C# and ASP.NET Core applications.