How Constant Are Your Constants in .NET

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.
    /// 
    [STAThread]
    static void Main(string[] args)
    {
        for(int i = 0; i < Library.CYCLES_NEEDED; i++)
        {
            //Do meaningful work...
            Console.WriteLine(i);
        }
    }
}

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.

Huh?

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:

[STAThread]
private static void Main(string[] args)
{
    for (int num1 = 0; num1 < 5; num1++)
    {
        Console.WriteLine(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.

What others have said

Requesting Gravatar... ThePaul Jan 02, 2005 10:20 AM
# re: How Constant Are Your Constants in .NET
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.
Requesting Gravatar... Haacked Jan 02, 2005 4:53 PM
# re: How Constant Are Your Constants in .NET
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.
Requesting Gravatar... Wayne Allen's Weblog Jan 02, 2005 11:52 PM
# .NET Constants are Really Constant
Requesting Gravatar... Pingback/TrackBack Jan 02, 2005 11:57 PM
# Wayne Allen's Blog
Wayne Allen's Blog
Requesting Gravatar... TOURNEY LOGIC LINK BLOG Jan 03, 2005 3:07 AM
# How Constant Are Your Constants in .NET (from: Haacked)
Requesting Gravatar... Koba Jan 06, 2005 9:24 AM
# re: How Constant Are Your Constants in .NET
Forget about Constants, tell me more about that cheap Viagra.
Requesting Gravatar... Marco Magdy Nov 20, 2007 4:33 AM
# re: How Constant Are Your Constants in .NET
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

http://blogs.msdn.com/brada/archive/2003/07/01/50101.aspx

Requesting Gravatar... Andrew Orlov Dec 04, 2008 11:37 PM
# re: How Constant Are Your Constants in .NET
Hmm... good )) but who use libraries for constants or enums only?
Usually you need to change logic.
Requesting Gravatar... Imran Amjad Sep 19, 2011 4:24 AM
# re: How Constant Are Your Constants in .NET
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.

What do you have to say?

(will show your gravatar)
Please add 8 and 6 and type the answer here: