Struct vs Class
programming
software development
C#
coding best practices

Why Choose Struct Over Class?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

In the development of software applications using languages such as C# or Swift, developers often encounter scenarios where they must choose between using a struct or a class. Understanding when to utilize a struct rather than a class is essential for optimal resource management, performance, and maintainability of code.

Understanding Structs and Classes

Classes

A class is a blueprint from which individual objects are created. These objects are reference types, meaning that they are stored on the heap, and the variable references point to the memory location where the actual data is stored.

Key characteristics of classes include:

  • Reference Type: Stored on the heap.
  • Inheritance: Supports inheritance, allowing for the creation of a new class that reuses the characteristics of an existing class.
  • Garbage Collection: Implemented in managed languages, cleaning up memory by removing objects that are no longer in use.

Structs

A struct, on the other hand, is a value type and is typically used to encapsulate small groups of related variables. Structs are stored on the stack or inline in containing types, making them lighter and often faster than classes.

Key characteristics of structs include:

  • Value Type: Stored on the stack or inline in containing objects.
  • No Inheritance: Does not support inheritance (except interfaces).
  • Memory Efficiency: Does not require garbage collection.

Reasons to Choose Struct Over Class

1. Performance

Structs are value types and are stored on the stack, providing faster allocation and deallocation times compared to classes, which are stored on the heap. Since structs are copied by value, when you pass a struct to a method, you are passing a copy rather than a reference, which can be more performant in certain scenarios where temporary objects are extensively used.

Example in C#

csharp
1struct Point
2{
3    public int X;
4    public int Y;
5}
6
7class Demo
8{
9    static void Main()
10    {
11        Point p1 = new Point { X = 10, Y = 20 };
12        Point p2 = p1; // Copies the data of p1 into p2
13        p1.X = 30;     // p2.X does not change, it remains 10
14
15        Console.WriteLine(p2.X); // Output: 10
16    }
17}

2. Immutable Data Types

Structs are often used to create immutable data types. Immutable data types do not allow for modification once they have been initialized. This is desirable for scenarios such as defining simple mathematical or geometrical points, or when thread-safety is a requirement without locks.

Swift Example

swift
1struct ImmutablePoint {
2    let x: Int
3    let y: Int
4}
5
6let point = ImmutablePoint(x: 1, y: 2)
7//point.x = 3 // Compiler error, as `x` is a constant

3. Reducing Memory Pressure

Since structs are not managed by the garbage collector, they are suitable for performance-critical applications, such as game development or real-time simulations, where high allocation rates can lead to increased garbage collection pauses and reduced performance.

4. Small Data Structures

Structs are ideal for small data structures that have a short life span or are logically considered as a single data entity. This can include coordinates, RGB values, or complex numbers.

5. Simple Collections

In languages that support generics, such as C# and Swift, structs can be used as elements within collections to reduce memory allocation and improve cache locality.

Key Considerations and Limitations

While structs are useful for the scenarios mentioned, they come with limitations:

  • Size Matters: If a struct is too large (typically more than 16 bytes), the cost of copying becomes significant.
  • No Polymorphism: Lack of class inheritance hierarchy limits polymorphic behavior.
  • Boxing Overhead: When a struct is cast to an object, boxing occurs, introducing additional overhead by moving the value from the stack to the heap.

Summary Table

FeaturesStructClass
TypeValue TypeReference Type
Memory AllocationStack or inline in containing objectsHeap
InheritanceNo (except interfaces)Yes
PerformanceBetter for small, transient dataBetter for large, complex data
MutabilityOften used immutablyMutable by default
Garbage CollectionNot RequiredRequired
Typical Use-CasesSmall, simple data structures Immutable typesLarge, complex object models Polymorphic behavior

Conclusion

Choosing between a struct and a class is crucial in achieving the desired balance between performance and functionality. Structs are advantageous in scenarios where performance is sensitive to memory allocation and deallocation, where data mutability is controlled, and where the overhead of inheritance is unnecessary. Understanding these distinctions ensures the optimal choice for efficient and maintainable software solutions.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.