Question

Most of time we represent concepts which can never be less than 0. For example to declare length, we write:

int length;

The name expresses its purpose well but you can assign negative values to it. It seems that for some situations, you can represent your intent more clearly by writing it this way instead:

uint length; 

Some disadvantages that I can think of:

  • unsigned types (uint, ulong, ushort) are not CLS compliant so you can't use it with other languages that don't support this
  • .Net classes use signed types most of the time so you have to cast

Thoughts?

Was it helpful?

Solution

“When in Rome, do as the Romans do.”

While there is theoretically an advantage in using unsigned values where applicable because it makes the code more expressive, this is simply not done in C#. I'm not sure why the developers initially didn't design the interfaces to handle uints and make the type CLS compliant but now the train has left the station.

Since consistency is generally important I'd advise taking the C# road and using ints.

OTHER TIPS

If you decrement a signed number with a value of 0, it becomes negative and you can easily test for this. If you decrement an unsigned number with a value of 0, it underflows and becomes the maximum value for the type - somewhat more difficult to check for.

Your second point is the most important. Generally you should just use int since that's a pretty good "catch-all" for integer values. I would only use uint if you absolutely need the ability to count higher than int, but without using the extra memory long requires (it's not much more memory, so don't be cheap :-p).

I think the subtle use of uint vs. int will cause confusing with developers unless it was written into developer guidelines for the company.

If the length, for example, can't be less than zero then it should be expressed clearly in the business logic so future developers can read the code and know the true intent.

Just my 2 cents.

I will point out that in C# you can turn on /checked to check for arithmetic overflow / underflow, which isn't a bad idea anyways. If performance matters in a critical section, you can still use unchecked to avoid this.

For internal code (ie code that won't be referenced in any interop manor with other languages) I vote for using unsigned when the situation warrants it, such as length variables as mentioned earlier. This - along with checked arithmetic - provides one more net for developers, catching subtle bugs earlier.

Another point in the signed vs unsigned debate is that some programmers use values such as -1 to indicate errors, when they wouldn't otherwise have meaning. I subscribe to the view that each variable should have only one purpose, but if you - or colleagues you code with - like to indicate errors in this way, leaving variables signed gives you the flexibility to add error states later.

Your two points are good. The primary reason to avoid it is casting, though. Casting makes them incredibly annoying to use. I tried using unisigned variables once but I had to sprinkle casts absolutely everywhere because the framework methods all use signed integers. Therefore, whenever you call a framework method, you have to cast.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top