I'm currently creating a unit test for a method.
The convert method this is supposed to test basically consists of return if value > 0
so I had the idea to check unsigned overflows as well.
While creating test cases for the test I stumbled upon this very peculiar behavior of the U
and UL
suffixes.
[DataTestMethod]
// more data rows
[DataRow(-1U, true)] // Technically compiles, but not to what I expected or "wanted"
[DataRow(-1UL, true)] // "CS0023: Operator '-' cannot be applied to operand of type 'ulong'"
// more data rows
public void TestConvertToBool(object value, bool result)
{
// For testing purposes
ulong uLong = -1UL; // "CS0023: Operator '-' cannot be applied to operand of type 'ulong'"
uint uInt = -1U; // "CS0266: Cannot implicitly convert type 'long' to 'uint'. An explicit conversion exists (are you missing a cast?) - Cannot convert source type 'long' to target type 'uint'"
var foo = -1U; // foo is of type 'long'
var bar = 1U; // bar is of type 'uint'
// ... do the actual assertion here
}
Why do they behave this way? Shouldn't it just overflow to the max values of uint
and ulong
?
I couldn't find any answer to this. The reference source seems to only contain the wrapper objects UInt32
and such that don't include any operators.
Note: I'm aware that there is no real point in doing this in the first place. I just found the behavior to be very unexpected.
It seems that it's converting the uint to a long so that there are always enough bits to store the entire potential range of resulting positive and negative values. The - operator can't be applied to a ulong because there's no larger type to convert it to