7

I've seen these 2 guidelines in coding c# standard and I’m not sure the what the 2nd one means.

  1. With the exception of zero and one, never hard-code a numeric value; always declare a constant instead.
  2. Use the const directive only on natural constants such as the number of days of the week.

What is the definition of a natural constants and if the number is not a natural constants given the 1st rule how does one declare a constant in c# without the const directive?

So how is the 2nd rule not contradicting the 1st rule for non natural constants?

See http://www.scribd.com/doc/10731655/IDesign-C-Coding-Standard-232 for reference.

4
  • 4
    As an aside, part of the motivation for #2 is that in C#, constants are baked into assemblies which reference them. See SO discussion here
    – Brian
    Commented Nov 27, 2012 at 20:06
  • @Brian: That's not an aside, that's obviously the real reason for the coding standards. Note that #1 says "constant", #2 says "const directive". If you have a constant that doesn't meet rule #2 you need to declare it readonly instead. Commented Nov 28, 2012 at 4:07
  • Deadlink - maybe because I don't have a subscription?
    – Evorlor
    Commented Aug 15, 2022 at 16:04
  • I will say that I agree the two rules are in conflict--while a good number of constants are well known such as the examples shown in the answers below, there are constants that are only germane to your application. Common example would be a parser that declares the tokens as constants. They may not be natural, but it's a lot easier to have the compiler enforce your spelling than to introduce subtle bugs because you can't guarantee a value never changes. When you have an unchanging value, const is your friend. Commented Aug 16, 2022 at 20:44

5 Answers 5

7

You cannot declare a "constant" without the const directive. When it refers to "natural constants" it's simply referring to values which are defined by an immovably obvious guarantee, something that is axiomatic, for example:

There are 7 days in a week. This will never change.

There are 12 inches in a foot. This will never change.

These seem pretty fixed and hard to identify relatably to a real situation though, there are however fixed guarantees similar to this which you can find in your own systems surely.

For example, say you're writing a web service, and you are versioning the contracts as you should, so you have an OblogonRepository service, it would be reasonable to claim inside that service:

This is version 1 of the OblogonRepository. This will never change.


Now that all of that has been said, let me go on to say, this rule sounds very restrictive and I don't particularly agree with it.

It is however very important to understand the behaviour of a const in C#, in relation to this: Everywhere a const is referenced, it will at compile time be replaced by a fixed reference to the literals in the assemblies table. This means if you have other assemblies referencing this const, and you compile them then recompile the assembly with the const with changed values, the referencing assemblies will not have the const value updated until you recompile them.

Do be cautious with consts, but in my personal subjective opinion, this rule is far more restrictive than is useful. Using consts for things like max allowed users or column numbers is completely common idiomatic C#, even though they may change unlike "natural numbers".

Here's a little further reading on consts which details their compile time behaviour: Link

This article claims a rule which sounds pretty spot on to me (emphasis mine):

Thus, const should be used mainly for values that are not subject to change, or [can be used] freely if the scope of the const is limited to the same assembly or smaller.

1
  • 1
    +1 for "or can be used freely if the scope of the const is limited to the same assembly or smaller"! In this scenario, in my mind it becomes "use const if you are certain the value shouldn't change for duration of program run time".
    – Justin
    Commented May 8, 2013 at 14:02
3

I think you can read "Natural Constant" as "This is a well-known and well-understood number, and is unlikely to ever change." Constants like e and pi meet this definition.

Magic numbers like seeds for pseudo-random number generators are not natural constants and, according to this coding standard, are better served by using the readonly keyword.

4
  • And what's your opinion and practice on this? Do you follow this applying readonly instead of const for simple magic numbers where you wish to avoid unnamed literals in a class? Or are you just explaining the rule being asked about regardless of your own non-compliance with it? Commented Nov 27, 2012 at 19:34
  • But the 1st rule says "always declare a constant instead" not readonly. Personally I feel the 2nd should be removed and it using const is fine for non natural constant values. Or the 2nd rule needs more clarification. Commented Nov 27, 2012 at 19:39
  • @JimmyHoffa: As long as breakage doesn't occur if the constant is changed (as described in your answer), I think using constants is OK for most any magic number. I do see the merit in using readonly for constants that are likely to change at some point, and numbers which cross assembly boundaries. Commented Nov 27, 2012 at 20:13
  • Just wanted to force you to disagree with the rule because I knew you did. I win. :D Commented Nov 27, 2012 at 20:20
3

Let's pretend that you have been tasked with writing an program that manages a satellite's trajectory in orbit. You wrote this program expecting the satellite to orbit earth, so all your calculation is done with a gravity constant of 9.81. Well, NASA decides to send this satellite to the Moon, where the gravity is 1/6 of the earth. You hard coded the gravity constant in your app, so Joe Schmo goes through your source code, changing all instances of 9.81 to 1.66. Except Joe Schmo forgot to change 1 formula, and the multi-billion dollar satellite crashes and burns on the moon's surface because 1 formula was using Earth's gravitational constant. By declaring a constant for gravity and using that constant every place you need gravity, any change to that constant can be implemented by changing 1 line of code, instead of five thousand lines.

So that's the WHY one should use constants instead of hard coding them in.

You cannot declare a constant without using the const directive. And if you are declaring a constant, use the const directive. You can only assign a constant a value when you declare it. For example:

   public const float Gravity = 9.81;
   Gravity = 1.6;

will not compile because you are attempting to change the value of a constant.

A natural constant is something that will never change: The length of an inch. The acceleration due to gravity on earth. The number of days in a week. The number of days in January. The ratio of cms to inches. These are all natural constants.

2
  • This is not really answering my question, the 1st seem perfectly clear, but the 2nd rule seems to contradict the 1st when the number is not a natural constant, in this case how should one not hard code the number without using const. It the 2nd rule suggesting using a readonly variable? Commented Nov 27, 2012 at 19:29
  • @Nathan Wilfert That's exactly what the 2nd rule is suggesting. If a number is not a natural constant, but you don't want it to change during execution of the program, then use readonly.
    – CurtisHx
    Commented Nov 28, 2012 at 11:47
0

What you get when you use a constant is a description of the value and a single point of change. A constant is a hard-coded value. All the uses of the constant variable are replaced with the actual value at compile time.

As for when to use const... you can use a const or you can't. I use const whenever I can, my program will have to track one less variable and will be that much more efficient.

0

Let’s say I use the constant 24 for number of hours in a day. That number is never going to change. I also use a constant 24 for number of items printed per page. That number could change, so I should give it a name.

But hours per day should also be named, because otherwise every time I see that constant 24 I don’t know what constant it is - hours per day, lines per page etc.

So any small numbers should be named. If I see 3.141592653589 I actually now it is pi, you don’t need to name it. And 0, 1, possibly 2, mean exactly that. They shouldn’t be named.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.