C# Enums
$count++; if($count == 1) { include "../mobilemenu.php"; } if ($count == 2) { include "../sharemediasubfolder.php"; } ?>
Enums (short for Enumerations) are a powerful feature in C# that allow developers to define a set of named integral constants. Enums enhance code readability, maintainability, and type safety by providing meaningful names for sets of related values. This comprehensive guide delves into everything you need to know about Enums in C#, including declaration, usage, best practices, common mistakes, and advanced topics.
Table of Contents
- Introduction to Enums - What is an Enum?
- Declaring Enums - Basic Declaration
- Using Enums - Assigning Enum Values
- Flags Enums - What are Flags Enums?
- Advanced Topics - Enum Methods
- Best Practices for Enums
- Common Mistakes with Enums
- Real-World Example
- Summary
- Benefits of Using Enums
- Specifying Underlying Types
- Explicit Value Assignment
- Default Values
- Casting Enums
- Parsing Enums from Strings
- Enum Methods and Operations
- Declaring Flags Enums
- Using Flags Enums
- Common Use Cases
- Enum Constraints in Generics
- Enum Serialization and Deserialization
- Working with Bitwise Operations
1. Introduction to Enums
What is an Enum?
An enum is a distinct type that consists of a set of named constants called the enumerator list. Enums are used to represent a collection of related values in a type-safe manner.Syntax:
enum EnumName
{
Member1,
Member2,
Member3,
// ...
}
Benefits of Using Enums
- Readability: Use meaningful names instead of numeric values.- Maintainability: Easier to manage and update related constants.
- Type Safety: Prevents invalid values from being assigned.
- IntelliSense Support: Enhanced developer experience with IDE support.
2. Declaring Enums
2.1 Basic Declaration
Example: Days of the Weekusing System;
enum DayOfWeek
{
Sunday, // 0
Monday, // 1
Tuesday, // 2
Wednesday, // 3
Thursday, // 4
Friday, // 5
Saturday // 6
}
class Program
{
static void Main()
{
DayOfWeek today = DayOfWeek.Friday;
Console.WriteLine($"Today is {today}"); // Output: Today is Friday
Console.WriteLine($"Numeric value: {(int)today}"); // Output: Numeric value: 5
}
}
Sample Output:
Today is Friday
Numeric value: 5
- Enum Declaration: `DayOfWeek` enum with days as members.
- Default Values: Members are assigned integer values starting from `0`.
- Casting: Enums can be cast to their underlying integer values.
2.2 Specifying Underlying Types
By default, the underlying type of enum members is `int`. However, you can specify a different integral type.Supported Underlying Types:
- `byte`, `sbyte`
- `short`, `ushort`
- `int`, `uint`
- `long`, `ulong`
Example: Enum with Byte Underlying Type
using System;
enum ErrorCode : byte
{
None = 0,
NotFound = 1,
Invalid = 2,
Timeout = 3,
Unknown = 255
}
class Program
{
static void Main()
{
ErrorCode code = ErrorCode.Timeout;
Console.WriteLine($"Error Code: {code}"); // Output: Error Code: Timeout
Console.WriteLine($"Numeric value: {(byte)code}"); // Output: Numeric value: 3
}
}
Sample Output:
Error Code: Timeout
Numeric value: 3
- Underlying Type Specification: `ErrorCode` uses `byte` as its underlying type.
- Value Assignment: Explicit values assigned to enum members.
2.3 Explicit Value Assignment
You can assign specific values to enum members, which can be non-sequential or duplicate if needed.Example: HTTP Status Codes
using System;
enum HttpStatusCode
{
OK = 200,
Created = 201,
Accepted = 202,
NoContent = 204,
BadRequest = 400,
Unauthorized = 401,
NotFound = 404,
InternalServerError = 500
}
class Program
{
static void Main()
{
HttpStatusCode status = HttpStatusCode.NotFound;
Console.WriteLine($"Status: {status}"); // Output: Status: NotFound
Console.WriteLine($"Numeric value: {(int)status}"); // Output: Numeric value: 404
}
}
Sample Output:
Status: NotFound
Numeric value: 404
- Explicit Values: Assigns specific numeric values to enum members, useful for mapping to external systems or standards.
2.4 Default Values
If no values are explicitly assigned, enum members are assigned incrementing integer values starting from `0`.Example: Default Enum Values
using System;
enum Color
{
Red, // 0
Green, // 1
Blue // 2
}
class Program
{
static void Main()
{
Color favorite = Color.Green;
Console.WriteLine($"Favorite Color: {favorite}"); // Output: Favorite Color: Green
Console.WriteLine($"Numeric value: {(int)favorite}"); // Output: Numeric value: 1
}
}
Sample Output:
Favorite Color: Green
Numeric value: 1
- Auto-Incrementing Values: Enum members are automatically assigned incremental integer values starting at `0` if not explicitly specified.
3. Using Enums
Enums can be used in various ways to enhance code clarity and enforce type safety.3.1 Assigning Enum Values
Enums can be assigned directly using their named constants.Example: Assigning and Comparing Enums
using System;
enum TrafficLight
{
Red,
Yellow,
Green
}
class Program
{
static void Main()
{
TrafficLight currentLight = TrafficLight.Red;
Console.WriteLine($"Current Light: {currentLight}"); // Output: Current Light: Red
// Comparing Enums
if(currentLight == TrafficLight.Red)
{
Console.WriteLine("Stop!");
}
}
}
Sample Output:
Current Light: Red
Stop!
- Enum Assignment: `currentLight` is assigned `TrafficLight.Red`.
- Enum Comparison: Enums can be compared using equality operators for control flow.
3.2 Casting Enums
Enums can be cast to and from their underlying integral types.Example: Casting Enums
using System;
enum Status
{
Inactive = 0,
Active = 1,
Suspended = 2
}
class Program
{
static void Main()
{
// Casting enum to int
Status userStatus = Status.Active;
int statusValue = (int)userStatus;
Console.WriteLine($"Status Value: {statusValue}"); // Output: Status Value: 1
// Casting int to enum
int input = 2;
Status inputStatus = (Status)input;
Console.WriteLine($"Input Status: {inputStatus}"); // Output: Input Status: Suspended
}
}
Sample Output:
Status Value: 1
Input Status: Suspended
- Enum to Integer: Casting `Status.Active` to `int` yields `1`.
- Integer to Enum: Casting `2` to `Status` results in `Status.Suspended`.
3.3 Parsing Enums from Strings
Enums can be parsed from strings using methods like `Enum.Parse` and `Enum.TryParse`, enhancing flexibility in scenarios like user input or data deserialization.Example: Parsing Enums
using System;
enum Color
{
Red,
Green,
Blue,
Yellow
}
class Program
{
static void Main()
{
string input = "Green";
if(Enum.TryParse<Color>(input, out Color color))
{
Console.WriteLine($"Parsed Color: {color}"); // Output: Parsed Color: Green
}
else
{
Console.WriteLine("Invalid color.");
}
// Parsing with ignore case
string inputCase = "blue";
if(Enum.TryParse<Color>(inputCase, true, out Color colorCase))
{
Console.WriteLine($"Parsed Color (case-insensitive): {colorCase}"); // Output: Parsed Color (case-insensitive): Blue
}
}
}
Sample Output:
Parsed Color: Green
Parsed Color (case-insensitive): Blue
- Enum.TryParse: Safely attempts to parse a string to an enum value without throwing exceptions.
- Case-Insensitive Parsing: The second parameter `true` in `TryParse` allows case-insensitive parsing.
3.4 Enum Methods and Operations
Enums support various built-in methods and operations that facilitate their manipulation and interrogation.Example: Enum Methods
using System;
enum Season
{
Spring,
Summer,
Autumn,
Winter
}
class Program
{
static void Main()
{
// Get all enum values
Array seasons = Enum.GetValues(typeof(Season));
Console.WriteLine("Available Seasons:");
foreach(Season s in seasons)
{
Console.WriteLine(s);
}
// Check if a value is defined in the enum
bool isDefined = Enum.IsDefined(typeof(Season), "Summer");
Console.WriteLine($"Is 'Summer' defined? {isDefined}"); // Output: Is 'Summer' defined? True
// Get name from value
string seasonName = Enum.GetName(typeof(Season), 2);
Console.WriteLine($"Season with value 2: {seasonName}"); // Output: Season with value 2: Autumn
}
}
Sample Output:
Available Seasons:
Spring
Summer
Autumn
Winter
Is 'Summer' defined? True
Season with value 2: Autumn
- Enum.GetValues: Retrieves all values of the enum.
- Enum.IsDefined: Checks if a specific value or name exists in the enum.
- Enum.GetName: Retrieves the name of the enum member corresponding to a specific value.
4. Flags Enums
Flags Enums are used to represent a combination of options or settings using bitwise operations. They allow for more flexible and expressive code when multiple values can be combined.4.1 What are Flags Enums?
A Flags Enum is an enumeration where each member represents a bit field, allowing multiple enum values to be combined using bitwise operations like OR (`|`) and AND (`&`).Key Points:
- [Flags] Attribute: Indicates that the enum can be treated as a bit field.
- Power of Two Values: Each enum member should be assigned values that are powers of two to ensure unique bit flags.
- Combination of Flags: Allows representing multiple options simultaneously.
4.2 Declaring Flags Enums
Syntax:[Flags]
enum EnumName
{
None = 0,
Option1 = 1 << 0, // 1
Option2 = 1 << 1, // 2
Option3 = 1 << 2, // 4
// ...
All = Option1 | Option2 | Option3
}
Example: File Access Permissions
using System;
[Flags]
enum FileAccessPermissions
{
None = 0,
Read = 1 << 0, // 1
Write = 1 << 1, // 2
Execute = 1 << 2, // 4
ReadWrite = Read | Write, // 3
All = Read | Write | Execute // 7
}
class Program
{
static void Main()
{
FileAccessPermissions permissions = FileAccessPermissions.Read | FileAccessPermissions.Execute;
Console.WriteLine($"Permissions: {permissions}"); // Output: Permissions: Read, Execute
Console.WriteLine($"Has Write Permission: {permissions.HasFlag(FileAccessPermissions.Write)}"); // Output: Has Write Permission: False
}
}
Sample Output:
Permissions: Read, Execute
Has Write Permission: False
- [Flags] Attribute: Indicates that the enum can be treated as a bit field for bitwise operations.
- Combination: `Read | Execute` combines the `Read` and `Execute` permissions.
- HasFlag Method: Checks if a specific flag is set.
4.3 Using Flags Enums
Flags enums allow combining multiple enum members to represent complex states or configurations.Example: Combining Flags
using System;
[Flags]
enum Days
{
None = 0,
Monday = 1 << 0, // 1
Tuesday = 1 << 1, // 2
Wednesday = 1 << 2, // 4
Thursday = 1 << 3, // 8
Friday = 1 << 4, // 16
Saturday = 1 << 5, // 32
Sunday = 1 << 6, // 64
Weekend = Saturday | Sunday // 96
}
class Program
{
static void Main()
{
Days meetingDays = Days.Monday | Days.Wednesday | Days.Friday;
Console.WriteLine($"Meeting Days: {meetingDays}"); // Output: Meeting Days: Monday, Wednesday, Friday
// Adding a day
meetingDays |= Days.Tuesday;
Console.WriteLine($"Updated Meeting Days: {meetingDays}"); // Output: Updated Meeting Days: Monday, Tuesday, Wednesday, Friday
// Removing a day
meetingDays &= ~Days.Wednesday;
Console.WriteLine($"Final Meeting Days: {meetingDays}"); // Output: Final Meeting Days: Monday, Tuesday, Friday
}
}
Sample Output:
Meeting Days: Monday, Wednesday, Friday
Updated Meeting Days: Monday, Tuesday, Wednesday, Friday
Final Meeting Days: Monday, Tuesday, Friday
- Combining Flags: Use bitwise OR (`|`) to add flags.
- Removing Flags: Use bitwise AND with the complement (`& ~`) to remove flags.
4.4 Common Use Cases for Flags Enums
- Permissions and Access Control: Representing combinations of user permissions.- State Representation: Managing multiple states or statuses simultaneously.
- Configuration Settings: Combining various configuration options.
Example Use Case: Network Packet Flags
using System;
[Flags]
enum PacketFlags
{
None = 0,
SYN = 1 << 0, // 1
ACK = 1 << 1, // 2
FIN = 1 << 2, // 4
RST = 1 << 3, // 8
PSH = 1 << 4, // 16
URG = 1 << 5 // 32
}
class Program
{
static void Main()
{
PacketFlags flags = PacketFlags.SYN | PacketFlags.ACK;
Console.WriteLine($"Packet Flags: {flags}"); // Output: Packet Flags: SYN, ACK
// Checking if FIN flag is set
bool hasFIN = flags.HasFlag(PacketFlags.FIN);
Console.WriteLine($"Has FIN flag: {hasFIN}"); // Output: Has FIN flag: False
// Adding FIN flag
flags |= PacketFlags.FIN;
Console.WriteLine($"Updated Packet Flags: {flags}"); // Output: Updated Packet Flags: SYN, ACK, FIN
}
}
Sample Output:
Packet Flags: SYN, ACK
Has FIN flag: False
Updated Packet Flags: SYN, ACK, FIN
- Initial Flags: Combines `SYN` and `ACK` flags.
- Flag Checks: Determines if a specific flag (`FIN`) is set.
- Flag Modification: Adds `FIN` flag using bitwise OR.
5. Advanced Topics
5.1 Enum Methods
Enums in C# come with several built-in methods that facilitate their manipulation and interrogation.Example: Using Enum Methods
using System;
enum Status
{
Inactive = 0,
Active = 1,
Suspended = 2,
Deleted = 3
}
class Program
{
static void Main()
{
// Get all enum values
Array statuses = Enum.GetValues(typeof(Status));
Console.WriteLine("All Statuses:");
foreach(Status s in statuses)
{
Console.WriteLine(s);
}
// Check if a value is defined
bool isDefined = Enum.IsDefined(typeof(Status), "Active");
Console.WriteLine($"Is 'Active' defined? {isDefined}"); // Output: True
// Get name from value
string statusName = Enum.GetName(typeof(Status), 2);
Console.WriteLine($"Status with value 2: {statusName}"); // Output: Suspended
// Parsing string to enum
string input = "Deleted";
if(Enum.TryParse<Status>(input, out Status parsedStatus))
{
Console.WriteLine($"Parsed Status: {parsedStatus}"); // Output: Parsed Status: Deleted
}
}
}
Sample Output:
All Statuses:
Inactive
Active
Suspended
Deleted
Is 'Active' defined? True
Status with value 2: Suspended
Parsed Status: Deleted
- Enum.GetValues: Retrieves all values of the `Status` enum.
- Enum.IsDefined: Checks if a specific name or value exists in the enum.
- Enum.GetName: Retrieves the name associated with a specific value.
- Enum.TryParse: Attempts to parse a string into an enum value safely.
5.2 Enum Constraints in Generics
C# allows adding constraints to generic types to ensure they are enums. Starting from C# 7.3, you can use the `where T : Enum` constraint.Example: Generic Method with Enum Constraint
using System;
class Program
{
static void Main()
{
PrintEnumValue(Status.Active);
PrintEnumValue(DayOfWeek.Monday);
}
static void PrintEnumValue<T>(T enumValue) where T : Enum
{
Console.WriteLine($"{enumValue} = {(int)(object)enumValue}");
}
}
enum Status
{
Inactive = 0,
Active = 1,
Suspended = 2,
Deleted = 3
}
enum DayOfWeek
{
Sunday, // 0
Monday, // 1
Tuesday, // 2
Wednesday, // 3
Thursday, // 4
Friday, // 5
Saturday // 6
}
Sample Output:
Active = 1
Monday = 1
- Generic Constraint: The method `PrintEnumValue` ensures that only enum types can be passed as arguments.
- Casting to int: `(int)(object)enumValue` is used to convert the enum to its underlying integer value within a generic context.
5.3 Enum Serialization and Deserialization
Enums can be serialized and deserialized in various formats (JSON, XML, binary), which is essential for data storage, transmission, and interoperability.Example: JSON Serialization with Enums
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
enum Color
{
Red,
Green,
Blue,
Yellow
}
class Car
{
public string Make { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
public Color Color { get; set; }
}
class Program
{
static void Main()
{
Car car = new Car { Make = "Toyota", Color = Color.Green };
string json = JsonConvert.SerializeObject(car, Formatting.Indented);
Console.WriteLine("Serialized JSON:");
Console.WriteLine(json);
// Deserialize
Car deserializedCar = JsonConvert.DeserializeObject<Car>(json);
Console.WriteLine($"Deserialized Car: Make = {deserializedCar.Make}, Color = {deserializedCar.Color}");
}
}
Sample Output:
Serialized JSON:
{
"Make": "Toyota",
"Color": "Green"
}
Deserialized Car: Make = Toyota, Color = Green
- StringEnumConverter: Ensures that enums are serialized and deserialized as their string names instead of numeric values.
- Serialization: Converts the `Car` object with the `Color` enum to a JSON string.
- Deserialization: Reconstructs the `Car` object from the JSON string, correctly interpreting the enum.
5.4 Working with Bitwise Operations
Flags enums facilitate bitwise operations, allowing developers to manipulate and inspect combined enum values efficiently.Example: Bitwise Operations with Flags Enum
using System;
[Flags]
enum Permissions
{
None = 0,
Read = 1 << 0, // 1
Write = 1 << 1, // 2
Execute = 1 << 2, // 4
Delete = 1 << 3, // 8
FullControl = Read | Write | Execute | Delete // 15
}
class Program
{
static void Main()
{
Permissions userPermissions = Permissions.Read | Permissions.Write;
Console.WriteLine($"User Permissions: {userPermissions}"); // Output: Read, Write
// Add Execute permission
userPermissions |= Permissions.Execute;
Console.WriteLine($"Updated Permissions: {userPermissions}"); // Output: Read, Write, Execute
// Remove Write permission
userPermissions &= ~Permissions.Write;
Console.WriteLine($"Final Permissions: {userPermissions}"); // Output: Read, Execute
// Check if user has Delete permission
bool hasDelete = (userPermissions & Permissions.Delete) == Permissions.Delete;
Console.WriteLine($"Has Delete Permission: {hasDelete}"); // Output: Has Delete Permission: False
// Assign FullControl
userPermissions = Permissions.FullControl;
Console.WriteLine($"User Permissions: {userPermissions}"); // Output: FullControl
}
}
Sample Output:
User Permissions: Read, Write
Updated Permissions: Read, Write, Execute
Final Permissions: Read, Execute
Has Delete Permission: False
User Permissions: FullControl
- Removing Flags: Uses bitwise AND with the complement (`& ~`) to remove permissions.
- Checking Flags: Uses bitwise AND (`&`) to verify if a specific permission is set.
- FullControl: Represents all permissions combined.
6. Best Practices for Enums
Adhering to best practices ensures that enums are used effectively, enhancing code quality and maintainability.6.1 Use the [Flags] Attribute Appropriately
- Apply [Flags] Only When Needed: Use the `[Flags]` attribute for enums intended to be used as bit fields.- Avoid [Flags] for Single Options: Do not apply `[Flags]` to enums representing mutually exclusive states.
6.2 Provide Explicit Values
- Assign Values Carefully: Ensure that enum members have explicit values, especially when the underlying type is not `int`.- Maintain Consistency: Use consistent value assignments to prevent confusion and errors.
6.3 Use Singular Naming
- Enum Names: Use singular nouns for enum names (e.g., `DayOfWeek`, `Color`).- Member Names: Use clear and descriptive names for enum members.
6.4 Avoid Duplicate Values Unless Intentional
- Unique Values: Assign unique values to enum members unless multiple members are meant to represent the same value.- Clear Intent: Document or comment on why duplicate values exist to maintain clarity.
6.5 Implement Interfaces Carefully
- Prefer Generic Interfaces: When implementing interfaces, prefer generic versions like `IComparable- Limit Interface Implementations: Only implement necessary interfaces to keep enums simple and efficient.
6.6 Default Enum Member
- Meaningful Default: Ensure that the default enum member (`0`) represents a valid and meaningful state, such as `None` or `Unknown`.- Avoid Undefined Defaults: Prevent scenarios where the default value does not correspond to any defined enum member.
Example: Meaningful Default
using System;
enum Status
{
Unknown = 0,
Active = 1,
Inactive = 2,
Suspended = 3
}
class Program
{
static void Main()
{
Status defaultStatus = default(Status);
Console.WriteLine($"Default Status: {defaultStatus}"); // Output: Default Status: Unknown
}
}
Sample Output:
Default Status: Unknown
7. Common Mistakes with Enums
Avoiding common pitfalls ensures that enums are used correctly and efficiently.7.1 Duplicate Values
Mistake: Assigning the same value to multiple enum members unintentionally. Example:enum Status
{
Active = 1,
Inactive = 1, // Duplicate value
Suspended = 2
}
Issue: `Active` and `Inactive` both have the value `1`, which can lead to ambiguity.Solution: Ensure that each enum member has a unique value unless intentionally representing the same state.
7.2 Invalid Casting
Mistake: Casting integers that are not defined in the enum can lead to undefined or unexpected states. Example:using System;
enum Color
{
Red = 1,
Green = 2,
Blue = 3
}
class Program
{
static void Main()
{
int input = 4;
Color color = (Color)input;
Console.WriteLine($"Color: {color}"); // Output: Color: 4 (undefined)
}
}
Issue: The value `4` does not correspond to any defined member, leading to an undefined enum state.Solution:
- Use Enum.IsDefined: Check if a value is defined before casting.
- Use Enum.TryParse: Safely parse strings to enum values.
Corrected Example:
using System;
enum Color
{
Red = 1,
Green = 2,
Blue = 3
}
class Program
{
static void Main()
{
int input = 4;
if(Enum.IsDefined(typeof(Color), input))
{
Color color = (Color)input;
Console.WriteLine($"Color: {color}");
}
else
{
Console.WriteLine("Invalid color value.");
}
}
}
Sample Output:
Invalid color value.
7.3 Missing [Flags] Attribute for Bitwise Enums
Mistake: Forgetting to add the `[Flags]` attribute when designing enums for bitwise operations. Example:enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Execute = 4
}
Issue: Without `[Flags]`, combining enum members might not produce the expected string representation.Solution: Add the `[Flags]` attribute to indicate that the enum can be treated as a bit field.
Corrected Example:
using System;
[Flags]
enum Permissions
{
None = 0,
Read = 1,
Write = 2,
Execute = 4
}
class Program
{
static void Main()
{
Permissions userPermissions = Permissions.Read | Permissions.Execute;
Console.WriteLine($"User Permissions: {userPermissions}"); // Output: User Permissions: Read, Execute
}
}
7.4 Using Enums for Unrelated Constants
Mistake: Applying enums to represent unrelated or heterogeneous values, reducing code clarity.Example:
enum Settings
{
MaxUsers = 100,
Timeout = 30,
Theme = 1
}
Issue: `MaxUsers` and `Theme` represent different concepts (numeric limit vs. configuration option), leading to confusion.Solution: Use separate enums or appropriate data structures for unrelated constants.
7.5 Overusing Enums
Mistake: Using enums in situations where other data structures (like classes or structs) would be more appropriate, leading to rigid and less flexible code.Example:
enum UserType
{
Admin,
Guest,
RegisteredUser,
// Later adding more types becomes cumbersome
}
Issue: As requirements grow, adding more user types to the enum can lead to bloated and less manageable code.Solution: Use classes with inheritance or other design patterns for more complex scenarios.
8. Real-World Example
Example: Traffic Light Control System
Enums are ideal for representing states in a state machine, such as a traffic light system. This example demonstrates using enums to manage traffic light states and transitions.Code Example: Traffic Light Controller
using System;
using System.Threading;
enum TrafficLightState
{
Red,
Green,
Yellow
}
class TrafficLightController
{
private TrafficLightState _currentState;
public TrafficLightController()
{
_currentState = TrafficLightState.Red;
}
public void Start()
{
while(true)
{
DisplayState();
switch(_currentState)
{
case TrafficLightState.Red:
Thread.Sleep(3000); // Red for 3 seconds
_currentState = TrafficLightState.Green;
break;
case TrafficLightState.Green:
Thread.Sleep(3000); // Green for 3 seconds
_currentState = TrafficLightState.Yellow;
break;
case TrafficLightState.Yellow:
Thread.Sleep(1000); // Yellow for 1 second
_currentState = TrafficLightState.Red;
break;
}
}
}
private void DisplayState()
{
Console.Clear();
Console.WriteLine("Traffic Light State:");
switch(_currentState)
{
case TrafficLightState.Red:
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("RED");
break;
case TrafficLightState.Green:
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("GREEN");
break;
case TrafficLightState.Yellow:
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("YELLOW");
break;
}
Console.ResetColor();
}
}
class Program
{
static void Main()
{
TrafficLightController controller = new TrafficLightController();
controller.Start();
}
}
Explanation:- Enum Declaration: `TrafficLightState` defines possible states of a traffic light.
- State Management: The controller transitions between `Red`, `Green`, and `Yellow` states with specified durations.
- Display: The current state is displayed with corresponding console colors.
- Continuous Loop: The `Start` method runs an infinite loop to simulate continuous traffic light cycles.
Sample Output: A console window will display the current traffic light state in color, cycling through Red, Green, and Yellow with appropriate delays.
9. Summary
Enums in C# are a robust feature that provide a way to define a set of named integral constants, enhancing code readability, maintainability, and type safety. By leveraging enums effectively, developers can create more expressive and error-resistant code.Key Takeaways:
- Definition and Declaration: Enums are defined using the `enum` keyword and can have explicit underlying types and values.
- Usage: Enums can be assigned, compared, cast, and parsed, making them versatile for various scenarios.
- Flags Enums: With the `[Flags]` attribute, enums can represent combinations of values, useful for settings and permissions.
- Advanced Features: Enums support methods, generic constraints, serialization, and bitwise operations, providing extensive functionality.
- Best Practices: Use enums judiciously, ensure meaningful naming and values, apply the `[Flags]` attribute appropriately, and avoid common mistakes like duplicate values or invalid casting.
- Real-World Applications: Enums are ideal for state management, configuration settings, error codes, and more, enabling clear and maintainable code structures.
By mastering enums, you can effectively manage sets of related constants, leading to cleaner, more maintainable, and robust C# applications.