C# – Should I avoid using unsigned int in C#

cprogramming practices

I recently thought about the use of unsigned integers in C# (and I guess similar argument can be said about other "high level languages")

When In need of an integer I am normally not faced with the dilemma of the size of an integer, an example would be an age property of a Person class (but the question is not limited to properties) . With that in mind there is, as far as I can see, only one advantage of using an unsigned integer ("uint") over a signed integer ("int") – readability. If I wish to express the idea that an age can only be positive I can achieve this by setting the age type to uint.

On the other hand, calculations on unsigned integers can lead to errors of all sorts and it makes it difficult to do operations such as subtracting two ages. (I read this is one of the reasons Java omitted unsigned integers)

In the case of C# I can also think that a guard clause on the setter would be a solution that gives the best of two worlds, but, this would not be applicable when I for example, an age would be passes to some method. A workaround would be to define a class called Age and have the property age be the only thing there, but this pattern would have Me create many classes and would be a source of confusion (other developers would not know when an object is just a wrapper and when it's something more sofisticaded).

What are some general best practices regarding this issue? How should I deal with this type of scenario?

Best Answer

The designers of the .NET Framework chose a 32 bit signed integer as their "general-purpose number" for several reasons:

  1. It can handle negative numbers, especially -1 (which the Framework uses to indicate an error condition; this is why a signed int is used everywhere indexing is required, even though negative numbers are not meaningful in an indexing context).
  2. It's large enough to serve most purposes, while being small enough to be used economically almost anywhere.

The reason to use unsigned ints is not readability; it is having the capability to get the math that only an unsigned int provides.

Guard clauses, validation and contract preconditions are perfectly acceptable ways to insure valid numeric ranges. Seldom does a real-world numeric range correspond exactly to a number between zero and 232-1 (or whatever the native numeric range is of the numeric type you chose), so using a uint to constrain your interface contract to positive numbers is kind of beside the point.