How Constant Are Your Constants in .NET

0 comments suggest edit

Code Complete 2 Back in the day when I was a wet behind the ears developer a coworker gave me some sage advice. He told me that if I wanted to become a good developer, I need to read the bible. He was of course referring to Code Complete, the bible of software construction. When I was promoted to manager, I made it required reading for developers. Several years later, I’m reading through the second edition savoring every page like a fine glass of sake.

This time around, I have a lot more experience to provide context to what I’m reading. Around page 270 (Chapter 11 end of section 2) I came across McConnel’s recommendations about the use of constants and it got me thinking about how appropriate that advice is in the world of .NET.

McConnel discusses good and bad names for constants. An example of a poor name for a constant is FIVE. If you needed to change it to another value, it wouldn’t make any sense (const int FIVE = 6;). Instead choose a name that represents the abstract entity the constant represents. For example, CYCLES_NEEDED.

Another bad example he presents is BAKERS_DOZEN which he states would be better named as DONUTS_MAX.

Although I agree with him in principle, his advice might need to be modified in light of how constants are handled in .NET. For example, CYCLES_NEEDED probably shouldn’t be a constant if you think you might change the value later. Secondly, BAKERS_DOZEN might be a fine constant since it’s a value that will never change.

This boils down to a semantic issue. What exactly is a constant? Is it simply a variable with a value set at compile time often used to consolidate a setting in one place? Or is it a variable that holds a value that never changes, not even from build to build?

Well the answer of course is “it depends”. When you look at .NET however, it seems to favor the latter behavior. Suppose you’re building a class library that contains a public constant like so:

public class Library
    public const int CYCLES_NEEDED = 5;

And you build an application that references this assembly and makes use of the constant like so.

class MyApp
    /// The main entry point for the application.
    static void Main(string[] args)
        for(int i = 0; i < Library.CYCLES_NEEDED; i++)
            //Do meaningful work...

If you compile and run this simple program, the console will output the numbers 0 through 4 as you would expect. Yes, this is a complicated program. The result of many years of experience.

Now suppose it’s several weeks later and your boss storms into your office. The company is bleeding cash and he wants you to up the cycles to 6 to increase profit. “Why that’s simple” you say to yourself.

“I’ll just change the value of CYCLES_NEEDED, recompile my library assembly, and deploy the dll without touching the exe so that the downtime is minimized. I’m such a genius!”

So what happens when you do that? You get the same output as before.


When one assembly references a constant in another assembly, the compiler will embed the value of that constant into the assembly. For example, using Reflector to decompile the sophisticated console app presented above, the Main method is compiled as:

private static void Main(string[] args)
    for (int num1 = 0; num1 < 5; num1++)

So as you can see, in order to change the value of the constant, both the library and the consumer of the library have to be recompiled to reflect the change with the constant. If we anticipate that CYCLES_NEEDED might ever change, it would be better to make this a public static read only variable as such:

public class Library
    public static readonly int CYCLES_NEEDED = 5;

Now should you deploy a change to the value of CYCLES_NEEDED, the console application will pick up the change without needing to recompile it. This is especially important in cases where it’s much easier to deploy a dll rather than the entire application.

The only drawback to this approach is that the value needs to be obtained at run-time instead of having the value compiled into the app which is a slight performance hint. Well if you’re worried about this, I’d suggest that you’re suffering from a case of premature optimization and you need to go read Rico’s blog where he’ll tell you to measure measure measure. As McConnel states repeatedly in Code Complete, the greatest impediment to performance is most likely to be the overall architecture of your system and not minor code issues.

Of course, if you have full control over your libraries and clients of the libraries, this may not be as big an issue to you. However, if you have several production systems deployed, it’s nice to apply patches via deploying the least amount of code as possible.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.



6 responses

  1. Avatar for ThePaul
    ThePaul January 2nd, 2005

    Semantics indeed! If you plan on, or don't plan on (but still leave the door open to) changing the value sometime in the near or far future, then how can we call it a constant.

    "Is it simply a variable with a value set at compile time often used to consolidate a setting in one place? Or is it a variable that holds a value that never changes, not even from build to build? " -- Perhaps its neither? Maybe we should look at constants not as variables, but as constants.

    Is CYCLES_NEEDED comparable to SPEED_OF_LIGHT? Like you said, it depends.

    Great article, fun read.

  2. Avatar for Haacked
    Haacked January 2nd, 2005

    Good point. A constant variable is an oxymoron, which is fitting as I'm a moron who went to Oxy (Occidental College).

    In any case, I think using the const keyword to hold configuration like values will be a hard habit to break.

  3. Avatar for Koba
    Koba January 6th, 2005

    Forget about Constants, tell me more about that cheap Viagra.

  4. Avatar for Marco Magdy
    Marco Magdy November 20th, 2007

    unfortunately, looks like enums suffer from the same problem as constants.
    That kinda sucks.
    here is what the IL looks like of const:
    .field public static literal
    here is what it looks like for enums (per field):
    .field public static literal valuetype

  5. Avatar for Andrew Orlov
    Andrew Orlov December 4th, 2008

    Hmm... good )) but who use libraries for constants or enums only?
    Usually you need to change logic.

  6. Avatar for Imran Amjad
    Imran Amjad September 19th, 2011

    Well, If constants are to be changed ever, I'll make them configurable through App.Config. Don't need to recompile and redeploy anything in this case.