This is a question that came up on our internal alias. I thought it might be generally interesting to illustrate how the compiler picks operators.

Here is the original issue. This code compiles fine:

UInt64 vUInt641 = UInt64.MaxValue;
const int  vInt2 = 1432765098;
int res = (int)(vUInt641 - vInt2);

But this code generates a compile error:

UInt64 vUInt641 = UInt64.MaxValue;
int  vInt2 = 1432765098;
int res = (int)(vUInt641 - vInt2);

(line 3): error CS0019: Operator '-' cannot be applied to operands of type 'ulong' and 'int'

 The only difference between the two pieces of code is the presence of the const keyword in the first one. Let's first analyze the second case. The reason an error is generated is that there is no '-' operator defined between an ulong and an int. There is also no implicit conversion between int and and ulong or the other way around. The compiler has to give up and to produce an error.

In the first case the variable is marked as const, which means that the compiler knows its value at compile time. It realizes that the value is positive and can safely been converted to an ulong. The compiler converts it and then invokes the "-(ulong, ulong)" operator.

A bizarre way to think of it is this. As you have been nice to the compiler by telling him that you are not going to modify this value, the compiler then is nice to you by making use of the info to help you out in this case ...

Remember, always be nice to the compiler, the more you tell him, the more he tells you ...