How to Resolve Error "CS0221: Constant value 'value' cannot be converted to a 'type' (use 'unchecked' syntax to override)" in C#
The Compiler Error CS0221 is a data integrity error occurring at compile-time. The message reads: "Constant value 'value' cannot be converted to a 'type' (use 'unchecked' syntax to override)".
In C#, the compiler validates constant expressions immediately. If you attempt to assign a constant value (like a large literal number or a specific floating-point state like Infinity) to a variable type that cannot support it, the compiler stops you. It assumes this is a mistake because the conversion would result in Data Loss, Overflow, or an Undefined State.
This guide explains why certain constant conversions are forbidden and how to force them if necessary using the unchecked keyword.
Understanding Constant Conversion Risks
When converting numbers types (e.g., double to int or ulong to int), two main issues can occur:
- Range Overflow: The source number is simply too big for the destination.
- Representation Mismatch: The source represents a concept (like
Infinity) that the destination cannot represent.
Because the values are constants (known at compile-time), the compiler sees the error immediately and flags CS0221 instead of letting the program crash at runtime.
Scenario 1: Converting Infinity or NaN to Integer
Floating-point types (float, double) can store special values like PositiveInfinity, NegativeInfinity, and NaN (Not a Number). Integer types (int, long) cannot.
Attempting to cast a constant Infinity to an int is strictly forbidden because there is no logical integer representation for "Infinity".
Example of error
public class MathConstants
{
// ⛔️ Error CS0221: Constant value 'Infinity' cannot be converted to a 'int'.
// An integer must be a finite number.
public const int InfiniteLoopLimit = (int)double.PositiveInfinity;
// ⛔️ Error CS0221: Same applies to NaN
public const int InvalidValue = (int)double.NaN;
}
Solution: Use Min/Max Values
Since integers cannot be infinite, use the maximum possible value for that type to represent "effectively infinite" in your logic.
public class MathConstants
{
// ✅ Correct: Use Int32.MaxValue to represent the upper bound
public const int InfiniteLoopLimit = int.MaxValue;
// ✅ Correct: Use 0 or -1 for invalid/missing values
public const int InvalidValue = 0;
}
Scenario 2: Numeric Overflow (Truncation)
This occurs when casting a massive integer literal (like a ulong) into a smaller signed type (like int). If the value is larger than int.MaxValue (2,147,483,647), the compiler protects you from accidental overflow.
Example of error: trying to force a large hexadecimal value into a signed integer.
public class BitMasks
{
// 0xFFFFFFFF is 4,294,967,295 (Too big for signed int)
// In binary, this looks like -1 if interpreted as signed,
// but the compiler sees it as a magnitude overflow first.
// ⛔️ Error CS0221: Constant value '4294967295' cannot be converted to a 'int'
public const int AllBitsOn = (int)0xFFFFFFFF;
}
Solution: Using the unchecked Keyword
If you deliberately want to perform this conversion—meaning you accept that the bits will be truncated or the sign will flip (overflow)—you must wrap the expression in the unchecked keyword.
This tells the compiler: "I know this value doesn't fit naturally. Just copy the bits into the destination type and ignore the mathematical value."
Solution:
public class BitMasks
{
// ✅ Correct: 'unchecked' forces the bitwise conversion.
// The result will be -1 due to Two's Complement representation.
public const int AllBitsOn = unchecked((int)0xFFFFFFFF);
}
public class Program
{
static void Main()
{
System.Console.WriteLine(BitMasks.AllBitsOn);
}
}
Output:
-1
Caution with Infinity:
Using unchecked works for integer overflow, but using unchecked((int)double.PositiveInfinity) generally results in 0 or int.MinValue depending on the environment (Result is formally undefined in C# specification for infinity-to-int casts). Avoid casting Infinity even with unchecked.
Conclusion
CS0221 acts as a safeguard against data corruption during compile-time constants calculation.
- Check Values: Are you trying to shove
double.Infinityinto anint? Useint.MaxValueinstead. - Check Range: Is the number too big? (e.g.,
longtoint). - Force Overflow: If you specifically want bitwise wrapping (common in flags/enums), use the
unchecked(...)syntax to override the error.