When you start learning C#, you’ll come across different types like Classes, Structs and Records. These types are essential for creating objects and managing data. Let’s break down what each of these types is, how they work, and how they differ from each other.

Classes

Classes are the most common type in C#. They are reference types, which means they store a reference to the data rather than the data itself.

Key Points:

  • Reference Type: Classes are stored on the heap.
  • Reference Sharing: When you assign one class instance to another, both variables refer to the same object.
  • Modifiable: You can change the properties of the object.

Example:

class Person
{
    public string Name { get; set; }
}

Person person1 = new Person { Name = "Alice" };
Person person2 = person1; // person2 and person1 refer to the same object

person2.Name = "Bob"; // Changing person2 also changes person1
Console.WriteLine(person1.Name); // Output: Bob
Console.WriteLine(person2.Name); // Output: Bob

Structs

Structs are value types, which means they hold the actual data directly. They are often used for small, simple objects that do not require complex behavior.

Key Points:

  • Value Type: Structs are stored on the stack.
  • Copying Data: When you assign one struct instance to another, a copy of the data is made.
  • Independent Copies: Changes to one struct instance do not affect another.

Example:

struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
}

Point point1 = new Point { X = 1, Y = 2 };
Point point2 = point1; // point2 is a copy of point1

point2.X = 3; // Changing point2 does not change point1
Console.WriteLine(point1.X); // Output: 1
Console.WriteLine(point2.X); // Output: 3

Records

Records are a special type introduced in C# 9. They are reference types, like classes, but they are designed to be immutable and provide built-in functionality for value equality.

Key Points:

  • Reference Type: Records are stored on the heap.
  • Immutable by Default: Records cannot be changed after creation.
  • Value-Based Equality: Records compare based on their values, not their references.

Example:

record PersonRecord(string Name);

PersonRecord record1 = new PersonRecord("Alice");
PersonRecord record2 = record1; // record1 and record2 refer to the same object initially

record2 = record2 with { Name = "Bob" }; // Creates a new record instance with Name = "Bob"

Console.WriteLine(record1.Name); // Output: Alice
Console.WriteLine(record2.Name); // Output: Bob

Clarifying Immutability in Records

A common question arises: If records are immutable, how can we change the Name from “Alice” to “Bob”? The answer lies in the with expression, which creates a new record instance with the updated value, leaving the original instance unchanged.

Here’s what happens:

  1. record1 is created with Name set to “Alice”.
  2. record2 is assigned to record1, so both reference the same object.
  3. record2 = record2 with { Name = "Bob" }; creates a new record instance based on record2 but with Name set to “Bob”.

This process doesn’t change record1 but creates a new record for record2.

Summary

  • Classes are reference types stored on the heap. When assigned, they share the same object.
  • Structs are value types stored on the stack. When assigned, they create independent copies.
  • Records are reference types that are immutable by default. The with expression creates new instances for modifications.

Understanding these differences helps you choose the right type for your data and ensures efficient memory management and performance in your C# applications.

Don’t forget to checkout: Simplify Your C# Projects with Global Using Directives

Categorized in:

.Net,

Last Update: June 20, 2024