Is there anyone able to explain me this strange behavior?
int i = 0x1234;
byte b1 = (byte)i;
byte b2 = (byte)0x1234; //error: const value
You shouldn't surround this with unchecked. Unchecked allows assignment of dangerous value types to a type, which may cause overflows.
byte b1 = (byte)i; will cause an overflow or cast exception at runtime.
byte b2 = (byte)0x1234; is invalid because you can't store values larger than 0xFF in a byte.
byte b3 = unchecked((byte)0x1234); will place either 0x34 or 0x12 (depending on the CLR implementation) into b3, and the other byte will overflow.
byte b4 = checked((byte)i); is the same as byte b1 = (byte)i;
byte b5 = (byte)(int)0x1234; will cast 0x1234 to an int, and then try to cast it to byte. Again, you can't convert 0x1234 to a byte because it's too large.