Apr 24

Constants are (really!) different from read-only fields. Unfortunately, there are still many people which can’t tell the difference between them, so I thought about writing a small post on this topic.

A constant is a symbol (ie, an alias) for value that *never* changes. That’s why you can only define constant primitive types (wtf? Primitive types? Don’t we have only value vs reference types in .NET? Good question…I’ll return to this in a future post :),,). When I say primitive type, I’m thinking about Boolean, Int32, Single, etc. Interestingly, there’s a small exception to this rule: the C# compiler does allow us to define a constant for a non-primitive type if we set that value to null (in my opinion, this is not that useful, but the truth is that you can do it!)

Whenever you use a constant, you’ll end up getting the value of the constant in the generated IL code. Suppose you’ve got assembly A with the following constant definition:

public sealed class Constants {
    public const String Message = "Hello!";
Whenever you write code like this:

You’ll really end up with something like this:

Console.WriteLine("Hello"); //you get the idea :)

Now, embedding the constant value means that the compiler won’t allocate any memory for that constant because its value will be “embedded” in the code. There is, however, one thing which could “hurt” you. Suppose that the constant is defined in one assembly (let’s call it assembly A) and it’s used in another (say, B). Since constants are “copied” to the resulting IL, that means that if you change the value of the constant, you can’t simply recompile assembly A and redeploy it. With constants, you’re forced to recompile both assemblies.

The solution to the previous “problem” is to use read-only fields. A read-only field is declared with the C#’s readonly modifier and it can only be written to from within a constructor (type or instance, depending on the field being static or not). So, if we need to get better “versioning” support for a “constant” value, we should resort to static read-only fields. Here’s some code which re-writes the previous example with fields:

public sealed class Constants {
    public static readonly String Message = "Hello!";

And now you should be able to change the value of Message and get away with recompiling only assembly A (in this case, there’s no need to recompile assembly B!). Btw, if you don’t believe me, you can always use .NET Reflector to see the final result (just don’t forget to compare the IL – and not the C# or VB.NET – for both cases).

I’d say that most of us don’t really care about this subtle differences. However, you should consider them whenever you start writing components that get reused for others. And that’s it for now. Stay tuned for more posts on “basic” .NET features.

7 comments so far

  1. Lukis
    1:15 pm - 4-27-2010

    Love the basics posts!

  2. Steffen Jørgensen
    7:29 am - 4-28-2010

    Great little post! It gave me a nice “a-ha” experience.

    I do have a question though:
    Is there any cases where I should choose a constant over a read-only field?

  3. luisabreu
    8:15 am - 4-28-2010

    I do use them most of the time because I generally write applications and not frameworks that should be used by other people 🙂

  4. Pauli Østerø
    4:12 pm - 5-1-2010

    IMHO constants in frameworks belongs to the framework itself and shouldn”t be used by “outsiders”. So just declare them as private or internal and you should be fine.

  5. Ciprian
    12:21 pm - 5-18-2010


    Regarding an article you wrote 3 years ago, about printing on zebra.

    Unfortunately, i cannot find the attachement from the article, zebra.rar.

    Do you still have it somewhere?

  6. luisabreu
    8:14 pm - 5-18-2010

    It seems like the guys that hosted the site deleted everything without any notice…send me an email and I”ll send the zip to you…

  7. LongMALLORY35
    9:01 am - 5-27-2010

    Various people in the world take the credit loans from various banks, because it is simple.