I’m curious to know why the C# compiler only gives me an error message for the second if statement.
enum Permissions : ulong
{
ViewListItems = 1L,
}
public void Method()
{
int mask = 138612833;
int compare = 32;
if (mask > 0 & (ulong)Permissions.ViewListItems > 32)
{
//Works
}
if (mask > 0 & (ulong)Permissions.ViewListItems > compare)
{
//Operator '>' cannot be applied to operands of type 'ulong' and 'int'
}
}
I’ve been experimenting with this, using ILSpy to examine the output, and this is what I’ve discovered.
Obviously in your second case this is an error – you can’t compare a
ulongand anintbecause there isn’t a type you can coerce both to. Aulongmight be too big for along, and anintmight be negative.In your first case, however, the compiler is being clever. It realises that const
1> const32is never true, and doesn’t include yourifstatement in the compiled output at all. (It should give a warning for unreachable code.) It’s the same if you define and use aconst intrather than a literal, or even if you cast the literal explicitly (i.e.(int)32).But then isn’t the compiler successfully comparing a
ulongwith anint, which we just said was impossible?Apparently not. So what is going on?
Try instead to do something along the following lines. (Taking input and writing output so the compiler doesn’t compile anything away.)
This will compile, even though the
ulongis a variable, and even though the result isn’t known at compile time. Take a look at the output in ILSpy:So, the compiler is in fact treating your
const intas aulong. If you makethirtytwo = -1, the code fails to compile, even though we then know thatgtwill always be true. The compiler itself can’t compare aulongto anint.Also note that if you make
xalonginstead of aulong, the compiler generates32Lrather than32as an integer, even though it doesn’t have to. (You can compare anintand alongat runtime.)This points to the compiler not treating
32as aulongin the first case because it has to, merely because it can match the type ofx. It’s saving the runtime from having to coerce the constant, and this is just a bonus when the coercion should by rights not be possible.