0

I think this is fairly language-independent, but if I'm wrong, then go for C# (or C or C++).

With "simple" magic values I mean things like this:

if (Value > 0)

or

while (Value < 0)

or

while (MyQueue > 0)

While writing this (pseudo-code above) it kinda struck me that it really only applies to something being compared to 0.

Anyway, what's the best way to handle these sort of magic values (considering readability, amount of keystrokes/code to create and name)?

It feels like extreme overkill having an entire (static) class (or enum, in C#) dedicated to this.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Marcus Hansson
  • 816
  • 2
  • 8
  • 17
  • 1
    Magic numbers aren't about how many characters they take to type out but about what they mean - whether they are obvious and constant in context. –  Oct 16 '11 at 18:20
  • depends on whether these magic numbers change or not. An example: If you want to check if the queue is empty and you compare the queue length with 0, you don't have to encapsulate 0 because and empty queue always has the length 0. Parametric values which can be adjusted should be wrapped inside an Enum/Class etc. If you have some complex conditions like "The queue is empty if there are no red items in it" write a helper function like `isEmpty(MyQueue)` – sled Oct 16 '11 at 18:23
  • Yeah, as I wrote, it really only applies when you compare something (like a queue!) against 0, checking the length/objects in list/etc. – Marcus Hansson Oct 16 '11 at 18:31
  • @delnan I did write "readability", which, in my world at least, is affected by what you wrote :) – Marcus Hansson Oct 16 '11 at 18:33

2 Answers2

1

Certain numbers are only considered "magic numbers" by their context. Some usages embody a simple concept that has nothing to do with the specific value of the number. For example, if you want to check if a list is not empty you might write one of the following statements:

if (list.Count != 0)

if (list.Count > 0)

if (list.Count >= 1)

Neither 0 nor 1 has any meaning beyond 'nothing' and 'something', and so the above three statements should be read as "not nothing", "more than nothing" and "at least something", and therefore I wouldn’t call their usages "magic numbers". There may be other ways to perform such a check without using any numbers at all. For example, in C# you could use the Any LINQ operator:

if (list.Any())

I find this to be more descriptive and enable story-like readability of code. Other languages may have other facilities to express concepts such as 'nothing', 'something', 'empty set', 'non-empty set', etc.

Allon Guralnek
  • 15,813
  • 6
  • 60
  • 93
1

As Allon Guralnek stated I also would use the Any() extension methods to check if a certain collection contains items. You can also write additional extension methods like

public static class MyExtensions {
  public static bool IsNegative(this int number) {
    return number < 0;
  }

  public static bool IsPositive(this int number) {
    return number > 0;
  }
}

And then write your loop or conditions as

if (Value.IsPositive())
while (Value.IsNegative())
while (MyQueue.IsPositive())

assuming Value and MyQueue are of type int.

Andreas
  • 6,447
  • 2
  • 34
  • 46
  • This is actually a very good way to take advantage of extension methods! +1 for you :) – Marcus Hansson Oct 17 '11 at 06:16
  • I would actually recommend against wrapping the most simple and indivisible parts of your code into extension methods. Any software developer of any level will understand `value > 0` and there's no magic number that needs to be replaced there. These methods will only serve to add an additional layer that only obscures rather than clarifies, and they pollute the IntelliSense list of every integer. Nevertheless, adding calculated properties to your own classes is very acceptable. For example, you could add `IsEmpty`, `HasItems` or `IsActive` properties, etc, to your classes. – Allon Guralnek Oct 22 '11 at 12:19