Class vs Record: Difference between class and record type in C#

A thumbnail showing C# code.

Class vs Record

The main difference between class and record type in C# is that a record has the main purpose of storing data, while a class defines responsibility. Records are immutable, while classes are not.

Simply put, a class is an OOP concept that wraps data with functionality, while a record represents a set of data.

Other differences between class and record type include:

  • We define records using the record keyword instead of the class keyword.
  • Records should not have any state changes after instantiation, while classes change properties.
  • We create new records from existing ones when we want to change state. With classes, we modify the existing ones.

When to use a record over a class?

Use a record when an object's only purpose is to contain public data. On other hand, use a class if your object has unique logic. Classes are mutable so even if they have the same data, doesn't mean they are the same.

For example, if we think about a class that represents a window. Two windows on a house can look the same, and have the same size and color, but they are not the same:

C# Class example illustration.
Classes have the same data, but they are not the same.

On the other hand, if we think of records as a just bag of data, we only care about data being the same:

C# Record example illustration.
Records have the same data, so they are considered equal.

What is immutability?

Immutability is the concept of an object that cannot change after creation. This is a useful concept because it helps you keep data integrity. It ensures that we don't accidentally change or corrupt data.

We often use immutable objects passing data objects, simplifying caching, and to reduce bugs. The record type supports immutability because they don't change after instantiation.

So if we want to change a record, we would create a new one and copy over the data while incorporating modifications. Unlike classes, records make it easy for us because they support nondestructive mutation.

Nondestructive mutation

Nondestructive mutation is creating a new object from an existing one, while copying over the data from the original object.

Unlike classes, records have a language-supported pattern for nondestructive mutation.

To use the nondestructive mutation in C#, we use the with keyword:

C#
var secondWindow = firstWindow with { Color = "Blue" };

In the example above, we use nondestructive mutation to copy the Window record with a different color.

Here's the full example:

C#
public record Window
{
    public int Size { get; init; }
    public string Color { get; init; }

}

var firstWindow = new Window { Size = 10, Color = "Red" };
Console.WriteLine(firstWindow); // Window { Size = 10, Color = Red }

var secondWindow = firstWindow with { Color = "Blue" };
Console.WriteLine(secondWindow); // Window { Size = 10, Color = Blue }

Class vs Record: Compiled code

You might be surprised, but records compile into classes:

Code showing how compiling records works.
Records compile to classes.

During compile-time, the compiler generates "class code" based on our record definition. The compiler adds members that make it easy to deal with equality, cloning, printing as a string, and much more.

So, that means that during runtime classes and records are the same.


Last modified on:
Download Free Software Developer Career Guide

I've used these principles to increase my earnings by 63% in two years. So can you.

Dive into my 7 actionable steps to elevate your career.