Exploring C# Custom Types: Understanding Records, Structs, and Classes
Tags: csharp, softwareengineering, softwaredevelopment
Published: 2024-05-18 13:59:41

## Introduction
As developers, we daily encounter the need to organize and manage data in our applications. Whether we are modeling complex entities, representing simple data structures, or ensuring data immutability, choosing the right construct is crucial. C# provides three primary user-defined types to help us with these tasks, classes, structs, and records. Each of these types has its unique characteristics and use cases, allowing us to tailor our approach to the specific needs of our code.
### What is a class?
A class is a blueprint for creating objects. It defines a type that can have fields, properties, methods. Classes are reference types and they are stored on the heap memory and their variables hold references to the actual data. Lets better look an example on how we are using a class.
#### Example
```csharp
// Definition
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public void Log()
    {
        Console.WriteLine($"Hello, my name is {FirstName} {LastName}");
    }
}

// Usage
Person person = new Person { FirstName = "Jane", LastName = "Smith" };
person.Log();
```
### What is a Struct?
A struct is a value type and their storage depends on the context in which they are used. While structs are often associated with the stack, they are not always stored there. When we declare a struct as a local variable within a method, it is typically stored on the stack, for example
```csharp
void SomeMethod()
{
    Point point = new Point(5, 10); // point here is stored on the stack
```
When a struct is a field of a class, it is stored on the heap along with the containing class instance, for example
```csharp
public class SomeClass
{
    public Point point; // point is stored on the heap with the SomeClass instance
}

SomeClass someClassInstance = new SomeClass();
```
When structs are elements of an array, the array itself is an object on the heap, so the structs are stored on the heap, for example
```csharp
Point[] points = new Point[10]; // points array and its elements are stored on the heap
```
Structs are typically used for small and simple objects and used to represent single values. Like classes structs may also have 
 fields, properties and methods. The main difference between and a struct is that a struct do not support inheritance. Lets give an example on how we can use a struct type.
#### Example
```csharp
// Definition
public struct Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public void Print()
    {
        Console.WriteLine($"Point at ({X}, {Y})");
    }
}

// Usage
Point point = new Point { X = 5, Y = 10 };
point.Print(); 
```
### What is a Record?
Records are a new type introduced in C# 9.0, designed to simplify working with immutable data. Like classes, records are reference types, but they come with built-in support for value-based equality and immutability, making them a powerful tool for managing data in a clean and intuitive way.
#### Example
```csharp
// Definition
public record Person
{
    public string FirstName { get; init; }
    public string LastName { get; init; }

    public void Log()
    {
        Console.WriteLine($"Hello, my name is {FirstName} {LastName}.");
    }
}

// Usage
var person = new Person { FirstName = "Jane", LastName = "Smith" };
person.Log();
```
### When to Use Each
- Class, use when you need a complex object that might require inheritance, mutable state or shared references
- Struct, use for small and simple objects that represent single values, especially when performance is critical
- Records, use them when you need an immutable object that is primarily defined by its data. Ideal for DTO (data transfer objects)

### Comparing Class, Struct, and Record

| Feature              | Class                      | Struct                       | Record                     |
|----------------------|----------------------------|------------------------------|----------------------------|
| Type                 | Reference                  | Value                        | Reference                  |
| Storage              | Heap                       | Stack                        | Heap                       |
| Inheritance          | Yes                        | No                           | Yes                        |
| Immutability         | Mutable by default         | Mutable by default           | Immutable by default       |
| Equality             | Reference-based            | Value-based                  | Value-based                |
| Usage                | Complex objects            | Small data structures        | Immutable data structures  |