How do I cast an int to an enum in C#?
To cast an int to an enum in C#, you can use explicit casting syntax (YourEnumType)intValue or the Enum.ToObject() method. Explicit casting is the most straightforward approach when you know the enum type at compile time, while Enum.ToObject() is useful for scenarios where the enum type is determined at runtime.
Contents
- Explicit Casting Method
- Enum.ToObject() Method
- Safety Considerations
- Best Practices
- Advanced Scenarios
- Complete Example
Explicit Casting Method
The most common and straightforward way to cast an int to an enum in C# is using explicit type casting:
public enum Status
{
Active = 1,
Inactive = 2,
Pending = 3
}
int statusCode = 2;
Status status = (Status)statusCode; // Status.Inactive
Key points about explicit casting:
- Manual conversion: When we convert int to enum, we perform explicit casting and we tell the compiler that we accept the risks of two types not being compatible source.
- Compiler safety: By forcing an int conversion explicitly, the compiler is treating enum as a special type - one of many options, not as an integer source.
- Syntax:
YourEnumType enumVariable = (YourEnumType)intValue;
// Basic example
public enum Day
{
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7
}
int dayNumber = 3;
Day day = (Day)dayNumber; // Day.Wednesday
Enum.ToObject() Method
When you need to work with enum types determined at runtime, Enum.ToObject() is the appropriate choice:
Type enumType = typeof(Status);
int numericValue = 2;
object boxedEnumValue = Enum.ToObject(enumType, numericValue);
Status status = (Status)boxedEnumValue; // Status.Inactive
When to use Enum.ToObject():
- Runtime scenarios: It can be used in cases, when you need dynamically get enum values (or maybe metadata (attributes) attached to enum values) source.
- Generic methods: Useful for creating generic extension methods:
public static T ToEnum<T>(this int value) where T : struct
{
return (T)Enum.ToObject(typeof(T), value);
}
// Usage
Status status = 2.ToEnum<Status>(); // Status.Inactive
Safety Considerations
When casting integers to enums, you should consider safety to avoid runtime exceptions:
Enum.IsDefined() for Validation
Before casting, you can check if the integer value corresponds to a defined enum member:
int statusCode = 5;
if (Enum.IsDefined(typeof(Status), statusCode))
{
Status status = (Status)statusCode;
}
else
{
// Handle invalid enum value
Console.WriteLine("Invalid status code");
}
Why validation is important:
- Without validation, casting an integer that doesn’t correspond to any enum member will still compile and run, but may cause unexpected behavior in your application
- This is particularly important when dealing with user input or data from external sources
Best Practices
1. Always Validate When Necessary
public static Status SafeCastToStatus(int code)
{
return Enum.IsDefined(typeof(Status), code)
? (Status)code
: throw new ArgumentException("Invalid status code");
}
2. Handle Undefined Values Gracefully
public static Status ToStatusOrDefault(int code, Status defaultValue = default)
{
try
{
return (Status)code;
}
catch
{
return defaultValue;
}
}
3. Use Extension Methods for Reusability
public static class EnumExtensions
{
public static T ToEnum<T>(this int value, T defaultValue = default) where T : struct
{
if (Enum.IsDefined(typeof(T), value))
{
return (T)Enum.ToObject(typeof(T), value);
}
return defaultValue;
}
}
// Usage
var status = 2.ToEnum<Status>(); // Status.Inactive
var invalidStatus = 99.ToEnum<Status>(); // default(Status)
Advanced Scenarios
1. Generic Enum Conversion
public static TEnum ToEnum<TEnum>(this int value) where TEnum : struct, IComparable, IFormattable, IConvertible
{
if (!typeof(TEnum).IsEnum)
{
throw new ArgumentException("TEnum must be an enumerated type");
}
if (Enum.IsDefined(typeof(TEnum), value))
{
return (TEnum)Enum.ToObject(typeof(TEnum), value);
}
// Handle bitwise flags if applicable
var candidates = Enum.GetValues(typeof(TEnum)).Cast<int>().ToList();
var isBitwise = candidates.Select((n, i) =>
{
if (i < 2) return n == 0 || n == 1;
return n / 2 == candidates[i - 1];
}).All(y => y);
if (isBitwise)
{
return (TEnum)Enum.ToObject(typeof(TEnum), value);
}
throw new ArgumentException($"Value {value} is not a valid value for enum {typeof(TEnum).Name}");
}
2. Handling Nullable Enums
public static TEnum? ToNullableEnum<TEnum>(this int? value) where TEnum : struct
{
if (value == null)
{
return null;
}
return value.Value.ToEnum<TEnum>();
}
Complete Example
Here’s a comprehensive example demonstrating different approaches:
using System;
public class Program
{
public enum UserStatus
{
Active = 1,
Inactive = 2,
Pending = 3,
Suspended = 4
}
public static void Main()
{
// Basic explicit casting
int statusValue = 3;
UserStatus status1 = (UserStatus)statusValue;
Console.WriteLine($"Status 1: {status1}"); // Status 1: Pending
// Using Enum.ToObject
UserStatus status2 = (UserStatus)Enum.ToObject(typeof(UserStatus), 4);
Console.WriteLine($"Status 2: {status2}"); // Status 2: Suspended
// Safe casting with validation
int userInput = 5;
UserStatus? safeStatus = SafeCastToUserStatus(userInput);
Console.WriteLine($"Safe Status: {safeStatus ?? UserStatus.Active}"); // Safe Status: Active
// Extension method approach
var status3 = 2.ToEnum<UserStatus>();
Console.WriteLine($"Status 3: {status3}"); // Status 3: Inactive
}
public static UserStatus? SafeCastToUserStatus(int value)
{
return Enum.IsDefined(typeof(UserStatus), value)
? (UserStatus)value
: null;
}
}
// Extension method for cleaner syntax
public static class EnumExtensions
{
public static T ToEnum<T>(this int value, T defaultValue = default) where T : struct
{
return Enum.IsDefined(typeof(T), value)
? (T)Enum.ToObject(typeof(T), value)
: defaultValue;
}
}
Conclusion
Casting an int to an enum in C# is straightforward with explicit casting, but important considerations include:
- Use explicit casting for simple, compile-time known scenarios:
(YourEnumType)intValue - Employ Enum.ToObject() for runtime type determination:
Enum.ToObject(enumType, intValue) - Always validate when dealing with external data using
Enum.IsDefined()to prevent runtime issues - Create extension methods for cleaner, more reusable code
- Handle edge cases like undefined values and nullable enums appropriately
The choice between explicit casting and Enum.ToObject() depends on whether you know the enum type at compile time or need to work with it dynamically. Both approaches are valid, but explicit casting is generally preferred for its simplicity and readability when the enum type is known in advance.
Sources
- How do I cast int to enum in C#? - Stack Overflow
- C#: How to convert int to enum? – Josip Miskovic
- c# - Why enums require an explicit cast to int type? - Stack Overflow
- 2 ways to convert/cast int to enum in C# - Arun Gudelli
- c# - Casting to enum vs. Enum.ToObject - Stack Overflow
- Convert Int to Enum in C# - TutorialTeacher