I know why this is not allowed:
ulong x = 0xFEDCBA9876543210;
long y = Int64.MaxValue;
Console.WriteLine(x < y);
Obviously, there is no way for the runtime to implicitly cast either operand to the other type or a larger type to make the comparison work.
Operator ‘<‘ cannot be applied to operands of type ‘ulong’ and ‘long’.
So, this is also not allowed (with MinValue and const):
ulong x = 0xFEDCBA9876543210;
const long y = Int64.MinValue;
Console.WriteLine(x < y);
Yet, this is allowed (with MaxValue instead):
ulong x = 0xFEDCBA9876543210;
const long y = Int64.MaxValue;
Console.WriteLine(x < y);
There is no overload of < accepting a ulong and long, but I saw with Reflector that this will silently convert Int64.MaxValue to a ulong. But this does not always happen. How does it work, and what considerations are the reason for this inconsistency?
One big difference between
long y = Int64.MaxValue; if (x < y)...andif (x < Int64.MaxValue)is that in the latter case the compiler can actually see the constant value if it desired to. It can see that the actual constant value fits in the ulong range and therefore an implicit cast is ok.For a plain variable
long y, the compiler can’t make any assumptions about what the runtime value of y is. Nevermind that the assignment statement is just one statement up; the compiler doesn’t keep track of values assigned to variables.As noted by DarkGray, a const var behaves as a constant since you have told the compiler that its value will never change.