Question
In C#, when should you use a struct instead of a class?
My current mental model is that a struct is useful when an item is mainly a small group of values that logically belong together.
I also came across these common guidelines:
- A
structshould represent a single value. - A
structshould have a memory footprint smaller than 16 bytes. - A
structshould not be changed after creation.
Are these rules reliable? More importantly, what does a struct mean semantically in C#?
Short Answer
By the end of this page, you will understand the difference between struct and class in C#, especially the idea of value semantics versus reference semantics. You will learn why structs are usually best for small, immutable values like coordinates, dates, or colors, when classes are a better fit, what the common guidelines really mean, and how to avoid common mistakes such as accidental copying and unexpected mutations.
Concept
In C#, struct and class can both group related data and behavior, but they represent different kinds of meaning.
A class is a reference type:
- Variables store a reference to an object.
- Multiple variables can refer to the same instance.
- Changes through one reference are visible through others.
- Classes are a natural fit for entities with identity, lifecycle, and shared mutable state.
A struct is a value type:
- Variables store the actual value directly.
- Assigning a struct usually copies the value.
- Each copy is independent.
- Structs are best for small data that conceptually behaves like a single value.
What a struct means semantically
The most important idea is this:
- Use a struct when the thing is defined by its value.
- Use a class when the thing is defined by its identity.
For example:
- A
PointwithX = 10andY = 20is usually just a value. If two points have the same coordinates, they are effectively the same value. - A
Customeris usually an entity with identity. Two customers may have the same name and age but still be different customers.
Mental Model
Think of a struct like a number written on paper.
If you write 42 on one paper and copy it to another paper, you now have two separate copies of the same value. Changing one paper does not change the other.
That is how a struct behaves.
A class is more like a house address.
If two people both write down the same address, they are both referring to the same house. If someone paints that house blue, everyone referring to that address now sees the blue house.
That is how a class behaves.
So the question is:
- Is this thing more like a value you copy around?
- Or more like an object that multiple parts of the program refer to?
If it is a value, use a struct.
If it is an object with identity, use a class.
Syntax and Examples
Basic syntax
public struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y)
{
X = x;
Y = y;
}
}
public class Customer
{
public string Name { get; set; }
public Customer(string name)
{
Name = name;
}
}
Example: struct copies by value
Point p1 = new Point(10, 20);
Point p2 = p1;
Console.WriteLine(p1.X); // 10
Console.WriteLine(p2.X); // 10
p2 = p1; copies the value. After that, p1 and p2 are separate values.
Example: class copies the reference
Step by Step Execution
Consider this example:
public struct Point
{
public int X;
public int Y;
}
Point p1 = new Point { X = 1, Y = 2 };
Point p2 = p1;
p2.X = 99;
Console.WriteLine($"p1: {p1.X}, {p1.Y}");
Console.WriteLine($"p2: {p2.X}, {p2.Y}");
Step by step
p1is created with valuesX = 1andY = 2.p2 = p1;copies the entire struct value.- Now
p1andp2contain the same data, but they are separate copies. p2.X = 99;changes onlyp2.p1stays unchanged.
Output:
p1: 1, 2
p2: 99, 2
Now compare that with a class:
Real World Use Cases
Good uses for struct
Coordinates and geometry
public readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y)
{
X = x;
Y = y;
}
}
Used in:
- graphics
- game development
- UI layout
- mapping tools
Measurements and units
Examples:
- distance
- temperature
- money-like simple value wrappers
- duration
These are naturally value-like and often immutable.
Small configuration values
A small group of settings that behaves as a single value can work well as a struct.
Interop and low-level data
Structs are common when working with:
- binary file formats
- memory layouts
- platform interop
- high-performance code
Better uses for class
Real Codebase Usage
In real C# projects, developers often use struct carefully and for specific reasons.
Common patterns with structs
Immutable value objects
A very common pattern is a readonly struct for small value objects.
public readonly struct Temperature
{
public double Celsius { get; }
public Temperature(double celsius)
{
Celsius = celsius;
}
}
This avoids accidental mutation and makes copying safe.
Representing coordinates, ranges, and identifiers
Developers often use structs for:
- coordinates
- dimensions
- ranges
- lightweight wrappers around primitive values
Equality by contents
Since structs are value-like, developers often expect equality to be based on contained values.
For example, two points with the same coordinates should usually be considered equal.
Common patterns with classes
Shared mutable state
If multiple parts of the app need to observe and modify the same object, a class is usually the right choice.
Validation and lifecycle logic
Common Mistakes
1. Making structs mutable
This is one of the biggest mistakes.
Broken example:
public struct Counter
{
public int Value;
}
Counter c1 = new Counter { Value = 5 };
Counter c2 = c1;
c2.Value++;
Console.WriteLine(c1.Value); // 5
Console.WriteLine(c2.Value); // 6
A beginner may expect c1 to change too, but it does not because c2 is a copy.
Avoid it
Prefer immutable structs:
public readonly struct Counter
{
public int Value { get; }
public Counter(int value)
{
Value = value;
}
}
2. Using structs for large data
Broken idea:
public struct HugeData
{
public A, B, C, D, E, F, G, H;
}
Comparisons
| Feature | struct | class |
|---|---|---|
| Type category | Value type | Reference type |
| Assignment | Copies the value | Copies the reference |
| Identity | Usually no separate identity | Usually has identity |
| Mutation | Best kept immutable | Often mutable |
| Typical size | Small | Any size |
| Default use case | Coordinates, dates, small value objects | Entities, services, complex state |
| Heap allocation | Often avoided in simple cases | Usually allocated as objects |
| Inheritance | Cannot inherit from another struct/class |
Cheat Sheet
Quick rule
Use a struct for small, immutable, value-like data.
Use a class for identity-based, shared, mutable, or larger objects.
Struct signs
- Represents one conceptual value
- Small in size
- Safe to copy
- Prefer immutable
- Examples: point, size, date range, amount
Class signs
- Has identity
- Shared by multiple parts of code
- Changes over time
- Larger or more complex state
- Examples: user, order, service, repository
Key syntax
public readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y)
{
X = x;
Y = y;
}
}
public class User
{
public string Name { get; ; }
}
FAQ
Is a struct always stored on the stack in C#?
No. That is a common simplification. Structs are value types, but where they are stored depends on context.
Are structs faster than classes?
Not always. Small structs can be efficient, but large structs may be expensive to copy. Choose based on meaning first, then measure performance.
Should all small types be structs?
No. Small size helps, but the type should also have value semantics. If identity matters, use a class.
Why are immutable structs recommended?
Because structs are copied by value. If they are mutable, it is easy to accidentally modify a copy instead of the original.
Can a struct have methods in C#?
Yes. A struct can have methods, properties, constructors, and overrides. It is not limited to raw data.
What does "represents a single value" mean?
It means the whole struct should conceptually behave as one thing, even if it contains multiple fields, like a point or a date range.
When in doubt, should I use class or struct?
Usually class, unless you clearly need value semantics and the type is small and immutable.
Mini Project
Description
Build a small geometry model that demonstrates when a struct is a good fit and when a class is a better fit. You will create a Point as a value type and a Shape as a reference type to see how copying works differently in practice.
Goal
Create a C# program that shows value-copy behavior with a struct and shared-reference behavior with a class.
Requirements
- Create a
readonly structnamedPointwithXandYproperties. - Create a
classnamedShapewith aNameproperty and aPointproperty calledPosition. - Show that assigning one
Pointvariable to another creates an independent copy.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
C# Type Checking Explained: typeof vs GetType() vs is
Learn when to use typeof, GetType(), and is in C#. Understand exact type checks, inheritance, and safe type testing clearly.
C# Version Numbers Explained: C# vs .NET Framework and Why “C# 3.5” Is Incorrect
Learn the correct C# version numbers, how they map to .NET releases, and why terms like C# 3.5 are inaccurate and confusing.