I was writing a piece of code that prevents an ushort from overflow/underflow'ing. Before that I try:
ushort a = 0; //ushort.MinValue
a -= 1; //returns 65535 (ushort.MaxValue)
Then I write the real code, and I expect this to "fail" (not able to detect underflow):
ushort oldValue, rate, delta;
ushort newValue = Math.Max(ushort.MinValue, oldValue - rate * delta);
Interestingly an error (CS0266) prevents me from building it. While I expect that C# will use the ushort Max(ushort, ushort) overload, it is using int Max(int, int) overload and that ushort values are converted into int automatically. Of course when I explicit cast the result to ushort this works fine.
This makes me think, is C# detecting that a possible underflow can occur, so it's using int to do the comparison for me?
This is because
oldValue - rate * delta's result is of typeint. This is because the "minimum data type" for which operators +, -, * and / are defined isint. Sobyte,ushort, etc. are converted tointfirst. Then, the result is again anint. So you need to cast explicitly toushort.Or you could use
Convert.ToUInt16which will raise an exception if an overflow occurs.