Structs (struct vs class)
A struct looks almost identical to a class, but there's one profound difference: a struct is a value type . It's copied when you assign or pass it, instead of shared by reference. Understanding value vs reference semantics is one of the most important things you'll learn in C# — it explains a whole category of "why did that change?!" bugs.
Learn Structs (struct vs class) in our free C# course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.
Part of the free C# course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Imagine handing a colleague a document. With a class , you share a single Google Doc — they edit it and your copy changes too, because it's the same document. With a struct , you photocopy the document and hand them the copy — they can scribble all over it and your original is untouched. That photocopy-on-handover behaviour is exactly what "value type" means.
1. Declaring a Struct
A struct can hold fields, a constructor, properties and methods — syntactically it's nearly a class. It's ideal for small bundles of data that represent a single value, like a 2D point. The classic example is Point : two coordinates plus a little behaviour.
2. Value vs Reference Semantics
This is the whole point of the lesson. When you assign a struct to a new variable, you get an independent copy — change one and the other is unaffected. When you assign a class , both variables point at the same object — change one and you change "both". Run this side-by-side comparison and let it sink in.
Your turn — complete a temperature struct by writing a computed property.
3. readonly Structs
Mutable structs are a known foot-gun: because they copy so freely, a "change" you make might land on a copy you didn't mean to touch. The modern best practice is to make structs readonly so they're immutable — operations return a new value instead of mutating in place. This removes the surprise entirely.
4. record struct
If you want value-copy semantics and the free value equality, ToString() , and deconstruction of a record, use a record struct . A readonly record struct is the ideal small immutable value type — it's exactly what types like Vector or Color should be.
These lines build and use a struct, but they're scrambled. Order them so the program compiles and prints the area.
Fields, then constructor, then methods make up the struct body; you must construct r before calling Area() on it.
1 — b is a copy, so changing b.N leaves a.N at 1.
5 — a and b reference the same object, so the change is shared.
True — record structs get generated value equality.
Build a small immutable value type that represents a colour and can print itself as a hex string. This is a textbook real-world use of a readonly struct .
Practice quiz
A struct is what kind of type?
- A reference type
- An interface
- A value type
- An abstract type
Answer: A value type. A struct is a value type - copied when assigned or passed - unlike a class, which is a reference type.
What happens when you assign one struct variable to another?
- You get an independent copy
- Both share the same object
- It throws an exception
- The original becomes null
Answer: You get an independent copy. Assigning a struct makes a full copy; changing the copy does not affect the original.
Given 'class C', after var b = a; b.X = 99; what is a.X (where a.X was 1)?
- 1
- 0
- null
- 99
Answer: 99. Classes are reference types - a and b point at the same object, so the change is shared and a.X is 99.
What does declaring a 'readonly struct' guarantee?
- It lives on the heap
- It can't be mutated after creation - every field is readonly
- It can be inherited
- It can be null
Answer: It can't be mutated after creation - every field is readonly. A readonly struct is immutable; operations return a new value instead of mutating in place.
Why are mutable structs discouraged?
- Because structs copy so freely, a 'change' may land on a copy you didn't mean to touch
- They're slower to allocate
- They can't have methods
- They always box
Answer: Because structs copy so freely, a 'change' may land on a copy you didn't mean to touch. Easy copying means mutations can hit an unintended copy; making structs readonly removes the surprise.
What extra features does a 'record struct' add over a plain struct?
- Inheritance support
- Heap allocation
- Generated value equality, ToString(), and deconstruction
- Null support
Answer: Generated value equality, ToString(), and deconstruction. A record struct is still a value type but the compiler generates value equality, ToString(), and deconstruction.
Can a struct inherit from another struct or class?
- Yes, like classes
- No - structs can't be the base for or derive from inheritance
- Only from interfaces' base classes
- Only from abstract structs
Answer: No - structs can't be the base for or derive from inheritance. Structs can implement interfaces and have methods, but they cannot participate in inheritance.
What does a struct constructor have to do before it finishes?
- Call base()
- Return a value
- Mark itself readonly
- Assign every field / auto-property
Answer: Assign every field / auto-property. CS0843 occurs if a struct constructor doesn't fully assign every field/auto-property before completing.
Roughly what size is a struct generally recommended to stay under?
- 1 byte
- 16 bytes
- 256 bytes
- 1 KB
Answer: 16 bytes. Microsoft's guideline is small (~16 bytes), immutable, and short-lived; larger data is expensive to copy.
Can a non-nullable struct variable be null?
- Yes, always
- Only in classes
- No, unless you use a nullable type like T?
- Only when readonly
Answer: No, unless you use a nullable type like T?. Value types can't be null by default; you need a nullable value type (T?) to allow null.