NeuroAgent

Complete Guide: Casting Int to Enum in C#

Learn how to cast int to enum in C# using explicit casting and Enum.ToObject() methods. Discover safety considerations, best practices, and complete code examples for robust enum conversions.

Question

How do I cast an int to an enum in C#?

NeuroAgent

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

The most common and straightforward way to cast an int to an enum in C# is using explicit type casting:

csharp
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;
csharp
// 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:

csharp
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:
csharp
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:

csharp
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

csharp
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

csharp
public static Status ToStatusOrDefault(int code, Status defaultValue = default)
{
    try
    {
        return (Status)code;
    }
    catch
    {
        return defaultValue;
    }
}

3. Use Extension Methods for Reusability

csharp
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

csharp
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

csharp
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:

csharp
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:

  1. Use explicit casting for simple, compile-time known scenarios: (YourEnumType)intValue
  2. Employ Enum.ToObject() for runtime type determination: Enum.ToObject(enumType, intValue)
  3. Always validate when dealing with external data using Enum.IsDefined() to prevent runtime issues
  4. Create extension methods for cleaner, more reusable code
  5. 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

  1. How do I cast int to enum in C#? - Stack Overflow
  2. C#: How to convert int to enum? – Josip Miskovic
  3. c# - Why enums require an explicit cast to int type? - Stack Overflow
  4. 2 ways to convert/cast int to enum in C# - Arun Gudelli
  5. c# - Casting to enum vs. Enum.ToObject - Stack Overflow
  6. Convert Int to Enum in C# - TutorialTeacher