8.0 What This Teaches
- Basic
enumsyntax and underlying integer types - Explicit values and conversions
[Flags]enums for bit sets- Extension methods on enums
- Pattern matching with
switchexpressions
enum module) are
objects with methods.
8.1 Basic Enum Syntax
enum Direction { North, South, East, West }
Direction d = Direction.North;
Console.WriteLine(d); // North
Console.WriteLine((int)d); // 0 - first member defaults to 0
8.2 Underlying Type and Explicit Values
enum HttpStatus : int
{
Ok = 200,
Created = 201,
BadRequest = 400,
NotFound = 404,
ServerError = 500
}
HttpStatus status = HttpStatus.NotFound;
Console.WriteLine(status); // NotFound
Console.WriteLine((int)status); // 404
// Parse from integer
HttpStatus s = (HttpStatus)200;
Console.WriteLine(s); // Ok
// Parse from string
HttpStatus parsed = Enum.Parse<HttpStatus>("Created");
Console.WriteLine(parsed); // Created
int. You can specify byte,
short, long, or any other integral type after the colon.
8.3 [Flags] Enums
[Flags] when members represent bits in a bit field. Assign
powers of two as values. Combine and test members with bitwise operators:
[Flags]
enum Permission
{
None = 0,
Read = 1,
Write = 2,
Execute = 4,
All = Read | Write | Execute
}
Permission p = Permission.Read | Permission.Write;
Console.WriteLine(p); // Read, Write
Console.WriteLine(p.HasFlag(Permission.Read)); // True
Console.WriteLine(p.HasFlag(Permission.Execute));// False
p |= Permission.Execute;
Console.WriteLine(p); // Read, Write, Execute
8.4 Enum Utility Methods
// Get all values
foreach (Direction d in Enum.GetValues<Direction>())
Console.Write($"{d} "); // North South East West
// Get all names
string[] names = Enum.GetNames<Direction>();
// Check if a value is defined
bool valid = Enum.IsDefined(typeof(Direction), "North"); // true
bool bad = Enum.IsDefined(typeof(Direction), "Up"); // false
// TryParse - safer than Parse
if (Enum.TryParse<Direction>("East", out Direction result))
Console.WriteLine(result); // East
8.5 switch with Enums
Direction dir = Direction.West;
string label = dir switch
{
Direction.North => "up",
Direction.South => "down",
Direction.East => "right",
Direction.West => "left",
_ => throw new ArgumentOutOfRangeException()
};
Console.WriteLine(label); // left
8.6 Example - All Together
// Enums - traffic light state machine with switch expression.
TrafficLight light = TrafficLight.Red;
for (int i = 0; i < 6; i++)
{
Console.WriteLine(Describe(light));
light = Next(light);
}
static string Describe(TrafficLight l) => l switch
{
TrafficLight.Red => "STOP",
TrafficLight.Yellow => "CAUTION",
TrafficLight.Green => "GO",
_ => "UNKNOWN"
};
static TrafficLight Next(TrafficLight l) => l switch
{
TrafficLight.Red => TrafficLight.Green,
TrafficLight.Green => TrafficLight.Yellow,
TrafficLight.Yellow => TrafficLight.Red,
_ => TrafficLight.Red
};
enum TrafficLight { Red, Yellow, Green }
STOP
GO
CAUTION
STOP
GO
CAUTION
8.7 Exercise
Exercise
- Define a
Seasonenum with four values. Write a switch expression that maps each season to a weather description string. - Define a
[Flags]enumDayOfWeek(not the built-in one) with values for each day. Create aPermissionvalue representing a Mon-Wed-Fri schedule and test each day withHasFlag. - Use
Enum.GetValues<Season>()to iterate and print all seasons with their integer value.
8.8 Common Mistakes
Casting an arbitrary int to an enum without validation
Direction d = (Direction)99; // no exception - d holds 99
Console.WriteLine(d); // 99 - not a named value!
Enum.IsDefined or Enum.TryParse
before casting from an external integer.
Forgetting powers of two in [Flags]
[Flags]
enum Bad { A = 1, B = 2, C = 3 } // C = 3 = A|B, not a distinct bit!
Using int instead of enum in APIs
int where an enum is appropriate loses type
safety and documentation. Callers must know valid values out of band. Use
the enum type in method signatures.
8.9 Key Terms
| Term | Meaning |
|---|---|
| enum | Named set of integer constants; provides type-safe symbolic names |
| underlying type | The integral type storing enum values; defaults to int |
| [Flags] | Attribute enabling bitwise combination of enum members |
| HasFlag | Tests whether a flags enum value includes a specific flag |
| Enum.GetValues<T> | Returns all declared values of an enum type |
| Enum.TryParse<T> | Parses a string to an enum value without throwing on failure |
| Enum.IsDefined | Tests whether a value is a declared member of an enum |