I have been having a little bit of a debate with a coworker lately. We are specifically using C#, but this could apply to any language with nullable types. Say for example you have a value that represents a maximum. However, this maximum value is optional. I argue that a nullable number would be preferable. My coworker favors the use of zero, citing precedent. Granted, things like network sockets have often used zero to represent an unlimited timeout. If I were to write code dealing with sockets today, I would personally use a nullable value, since I feel it would better represent the fact that there is NO timeout.
Which representation is better? Both require a condition checking for the value meaning "none", but I believe that a nullable type conveys the intent a little bit better.
Best Answer
Consider:
Language,
Framework,
Context.
1. Language
Using ∞ can be a solution for a maximum.
JavaScript, for example, has an infinity. C# doesn't¹.
Ada, for example, has ranges. C# doesn't.
In C#, there is
int.MaxValue
, but you cannot use it in your case.int.MaxValue
is the maximum integer, 2,147,483,647. If in your code, you have a maximum value of something, like a maximum accepted pressure before something explodes, using 2,147,483,647 has no sense.2. Framework
.NET Framework is rather inconsistent on this point, and its usage of magic values can be criticized.
For example,
"Hello".IndexOf("Z")
returns a magic value-1
. It maybe makes it easier (does it?) to manipulate the result:rather than using a custom structure:
but is not intuitive at all. Why
-1
and not-123
? A beginner may also mistakenly think that0
means "Not found" too or just mistype(position >= 0)
.3. Context
If your code is related to timeouts in network sockets, using something which was used by everyone for decades for the sake of being consistent is not a bad idea. Especially,
0
for a timeout is very clear: it's a value which cannot be zero. Using a custom class in this case may make things more difficult to understand:Duration
to 0 ifIsTimeoutEnabled
is true?IsTimeoutEnabled
is false, what happens if I setDuration
to 100?This can lead to multiple mistakes. Imagine the following piece of code:
The operation runs for ten seconds. Can you see what's wrong with this code, without reading the documentation of
Timeout
class?Conclusion
null
expresses well the idea that the value is not here. It's not provided. Not available. It's neither a number, nor a zero/empty string or whatsoever. Don't use it for maximum or minimum values.int.MaxValue
is strongly related to the language itself. Don't useint.MaxValue
for a maximum speed limit ofVehicle
class or a maximum acceptable speed for an aircraft, etc.Avoid magic values like
-1
in your code. They are misleading and lead to mistakes in code.Create your own class which would be more straightforward, with the minimum/maximum values specified. For example
VehicleSpeed
can haveVehicleSpeed.MaxValue
.Don't follow any previous guideline and use magic values if it's a general convention for decades in a very specific field, used by most people writing code in this field.
Don't forget to mix approaches. For example:
¹ You can create your own type which includes infinity. Here, I'm talking about native
int
type only.