Chapter 15: Enums and Structs
1. Enums – Named Constants (Super Clean & Readable)
Enums (short for enumerations) let you define a set of named constants that represent a group of related values.
Real-life analogy: Think of days of the week: Monday, Tuesday, Wednesday… Instead of using magic numbers (1 = Monday, 2 = Tuesday), you use meaningful names!
Basic Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
enum DayOfWeek { Sunday, // 0 by default Monday, // 1 Tuesday, // 2 Wednesday, // 3 Thursday, // 4 Friday, // 5 Saturday // 6 } |
Usage:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
DayOfWeek today = DayOfWeek.Wednesday; Console.WriteLine(today); // "Wednesday" Console.WriteLine((int)today); // 3 if (today == DayOfWeek.Friday) { Console.WriteLine("Weekend is coming! 🎉"); } |
Custom Values (you can assign your own numbers):
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
enum ErrorCode { None = 0, NotFound = 404, ServerError = 500, Unauthorized = 401 } |
2. Enums with [Flags] – Represent Multiple Choices
Sometimes you want one variable to hold multiple options at the same time (like permissions, days available, features enabled).
You use the [Flags] attribute + powers of 2 values.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[Flags] enum DaysAvailable { None = 0, // 00000000 Monday = 1, // 00000001 Tuesday = 2, // 00000010 Wednesday = 4, // 00000100 Thursday = 8, // 00001000 Friday = 16, // 00010000 Saturday = 32, // 00100000 Sunday = 64 // 01000000 } |
How to combine multiple flags:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
var myAvailability = DaysAvailable.Monday | DaysAvailable.Wednesday | DaysAvailable.Friday; Console.WriteLine(myAvailability); // "Monday, Wednesday, Friday" // Check if a flag is set if ((myAvailability & DaysAvailable.Friday) == DaysAvailable.Friday) { Console.WriteLine("I'm available on Friday! 😊"); } // Remove a day myAvailability &= ~DaysAvailable.Wednesday; // Remove Wednesday // Add a day myAvailability |= DaysAvailable.Sunday; |
Beautiful display (with ToString):
|
0 1 2 3 4 5 6 |
Console.WriteLine(myAvailability.ToString()); // "Monday, Friday, Sunday" |
3. Structs – Value Types (Like Lightweight Classes)
Structs are similar to classes, but they are value types (stored on the stack, copied by value).
When to use structs?
- Small, simple data containers
- Performance-critical code (games, math, coordinates)
- You want copy-by-value behavior (not reference)
Syntax:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
struct Point { public int X { get; set; } public int Y { get; set; } public Point(int x, int y) { X = x; Y = y; } public double DistanceTo(Point other) { int dx = X - other.X; int dy = Y - other.Y; return Math.Sqrt(dx * dx + dy * dy); } public override string ToString() => $"({X}, {Y})"; } |
Usage:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Point p1 = new Point(3, 4); Point p2 = p1; // COPY! (not reference) p2.X = 10; // p1 remains (3,4) Console.WriteLine(p1); // (3, 4) Console.WriteLine(p2); // (10, 4) Console.WriteLine($"Distance: {p1.DistanceTo(p2):F2}"); // 7.21 |
4. Structs vs Classes – The Big Differences
| Feature | Struct (Value Type) | Class (Reference Type) |
|---|---|---|
| Stored where? | Stack (or inline in other objects) | Heap |
| Assignment behavior | Copies the entire value | Copies the reference (same object) |
| Default value | All fields zeroed (0, false, null…) | null |
| Inheritance | Cannot inherit from other structs/classes (only interfaces) | Full inheritance possible |
| Performance | Faster for small data (no GC pressure) | Slower for small objects (heap + GC) |
| Best for | Small, immutable data (Point, DateTime, Color) | Complex objects (Person, Order, Car) |
| Can be null? | No (unless Nullable<T> or T?) | Yes |
| Boxing/unboxing | Yes (when cast to object/interface) | No |
Real example – Point as struct vs class
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
struct PointStruct { public int X, Y; } class PointClass { public int X, Y; } // Struct – copy PointStruct ps1 = new PointStruct { X = 5, Y = 10 }; PointStruct ps2 = ps1; ps2.X = 100; Console.WriteLine(ps1.X); // Still 5! // Class – reference PointClass pc1 = new PointClass { X = 5, Y = 10 }; PointClass pc2 = pc1; pc2.X = 100; Console.WriteLine(pc1.X); // Now 100! (same object) |
Mini-Project: Card Game with Enums & Structs
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
[Flags] enum Suit { None = 0, Hearts = 1, Diamonds = 2, Clubs = 4, Spades = 8 } enum Rank { Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King } struct Card { public Rank Rank { get; } public Suit Suit { get; } public Card(Rank rank, Suit suit) { Rank = rank; Suit = suit; } public override string ToString() { return $"{Rank} of {Suit}"; } public bool IsRed => (Suit & (Suit.Hearts | Suit.Diamonds)) != 0; } class Program { static void Main() { Card aceOfSpades = new Card(Rank.Ace, Suit.Spades); Card queenOfHearts = new Card(Rank.Queen, Suit.Hearts); Console.WriteLine(aceOfSpades); // Ace of Spades Console.WriteLine(queenOfHearts); // Queen of Hearts Console.WriteLine(queenOfHearts.IsRed); // True // Flags example Suit myHand = Suit.Hearts | Suit.Spades; Console.WriteLine($"My hand has: {myHand}"); // Hearts, Spades if ((myHand & Suit.Hearts) == Suit.Hearts) { Console.WriteLine("I have a heart card! ♥"); } } } |
Summary – What We Learned Today
- Enums → named constants (days, error codes, ranks…)
- [Flags] enums → combine multiple values with and check with &
- Structs → lightweight value types (stack, copied by value)
- Struct vs Class → use struct for small, immutable data; class for complex objects
Your Homework (Super Fun & Practical!)
- Create a new console project called EnumsAndStructs
- Create:
- Enum UserRole with flags: None, Viewer, Editor, Admin, SuperAdmin
- Struct GamePosition with X, Y, Z (float) and method DistanceTo(GamePosition other)
- Struct PlayingCard with Suit (flags enum) and Rank (enum)
- In Program.cs:
- Create a user with multiple roles (e.g., Editor + Admin)
- Check if they have Admin rights
- Create two cards, compare suits, check if red
- Create two GamePositions and calculate distance
Next lesson: Exception Handling – we’re going to make your programs bulletproof against crashes and errors!
You’re doing absolutely fantastic! 🎉 Any part confusing? Want more examples with flags or structs? Just tell me — I’m right here for you! 💙
