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.

What You'll Learn

💡 Real-World Analogy

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.

🧩 Reorder Challenge

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.

🧠 Quick Recall

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.

struct vs class — Decision Guide

struct

class

Kind

Value type

Reference type

On assignment

Copied

Shared (reference)

Lives on

Stack (usually)

Heap

Can be null

No (unless T?)

Yes

Inheritance

No

Best for

Small immutable values

Objects with identity/behaviour

Pro Tips

Common Errors (and the fix)

Frequently Asked Questions

Mini-Challenge: an RGB Color Struct

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 .

🎉 Lesson Complete

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.

Continue this course