C non-boxing conversion of generic enum to int?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In C#, converting an enum to an integer is easy when the enum type is known at compile time. The problem gets more subtle in generic code, because not every enum is backed by int, and many obvious conversion APIs box the value. So the real answer is: a fully general, safe, non-boxing conversion to int is not always possible, but there are efficient patterns when you know the enum's underlying type.
Why Boxing Shows Up
Enums are value types, but many convenience APIs accept object, Enum, or interfaces implemented through boxing. For example, these patterns can allocate or box:
In non-generic code, a direct cast such as (int)myEnum is fine when the underlying type really is int. In generic code, the compiler cannot assume that for TEnum.
Constrain the Generic Type Properly
Modern C# lets you constrain a generic parameter to enum types:
This constraint prevents unrelated value types from being passed in, but it still does not mean every TEnum can safely be reinterpreted as int. Some enums are backed by byte, short, long, and other integral types.
Safe Conversion When the Underlying Type Is Known to Be int
If you control the API and know that every enum passed in is backed by int, you can use Unsafe.As to reinterpret the bits without boxing.
This avoids boxing during the actual value read. The important guard is the Enum.GetUnderlyingType check. Without it, reinterpreting a non-int enum as int is incorrect.
Why There Is No Universal int Answer
Consider these enum declarations:
Neither one is naturally "an int enum". Converting them generically to int may require widening or truncation rules, and those rules are not universal. That is why the compiler cannot simply allow a generic cast from TEnum to int.
A More General Alternative
If the real goal is "get a numeric value from any enum", using long or ulong is often a better abstraction. You can then decide how to handle signedness and range explicitly.
This version is simple and correct for many cases, but it may box. That is often acceptable unless profiling proves the conversion is on a hot path.
When Performance Actually Matters
If enum conversion is happening inside a tight loop, serializer, parser, or high-frequency generic utility, micro-allocations can matter. In those cases:
- Prefer specialized overloads when possible
- Use
where TEnum : struct, Enum - Use
Unsafe.Asonly when the underlying type is guaranteed - Benchmark before adding complexity
For many business applications, the boxing cost is so small compared with I/O, database work, or UI updates that the simpler code is the better tradeoff.
Common Pitfalls
One common mistake is assuming every enum is backed by int. int is the default, but C# allows several other integral backing types.
Another issue is using Unsafe.As<TEnum, int> without checking the underlying type. That can reinterpret the wrong number of bytes and produce invalid results.
Developers also sometimes over-optimize too early. A non-boxing helper is only worth the extra complexity if profiling shows the conversion is frequent enough to matter.
Finally, do not confuse enum constraints with numeric constraints. where TEnum : struct, Enum guarantees that the type is an enum, not that it is directly castable to int.
Summary
- A generic enum cannot always be converted to
intsafely without extra assumptions. - '
where TEnum : struct, Enumis the right starting constraint for enum-based generic code.' - Use
Unsafe.As<TEnum, int>only when the enum is guaranteed to beint-backed. - If you need a fully general solution, correctness may matter more than eliminating boxing.
- Measure first before introducing unsafe or specialized conversion code.

