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:
record1
is created withName
set to “Alice”.record2
is assigned torecord1
, so both reference the same object.record2 = record2 with { Name = "Bob" };
creates a new record instance based onrecord2
but withName
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