I can't see why line#5 fails to compile whereas line#4 is ok.
static void Main(string[] args)
{
byte b = 0;
int i = (int)(0xffffff00 | b); // ok
int j = (int)(0xffffff00 | (byte)0); // error: Constant value cannot be converted to a 'int' (use 'unchecked' syntax to override)
}
Compile-time constants are checked differently to other code, basically.
A cast of a compile-time constant into a type whose range doesn't include that value will always fail unless you explicitly have an unchecked
expression. The cast is evaluated at compile time.
However, the cast of an expression which is classified as a value (rather than a constant) is evaluated at execution time, and handles overflow either with an exception (in checked code) or by truncating bits (in unchecked code).
You can see this slightly more easily using byte
and just a const
field vs a static readonly
field:
class Test
{
static readonly int NotConstant = 256;
const int Constant = 256;
static void Main(string[] args)
{
byte okay = (byte) NotConstant;
byte fail = (byte) Constant; // Error; needs unchecked
}
}
See more on this question at Stackoverflow