Const vs Static vs Readonly in C#

Just last week I had a new-to-ASP.NET developer (we'll call him Roger) ask me to explain what the difference was between a variable declared as const variable and that same variable declared as staticreadonly. I made some stuff up tried my best to break it down, but I don't think I did a good enough job. As many of my readers know, I don't enjoy being unable to explain things well.

So, Roger, this post is my official, on-the-record attempt at getting you an answer to your question. Let's find out what the difference is between const, readonly and static variables in C#, and when we should use each of these keywords.

Const

A variable declared as const (read: constant) must be assigned a value at declaration, and this value may not then change at a later time.

You want to use const when you have a variable whose value will not change, ever, during the time your application is being used. Further, any variable declared as const will also, implicitly, be declared static.

But that begs the question: what does static do?

Static

A static member (variable, method, etc) belongs to the type of an object rather than to an instance of that type. Hence, if we declare this:

This means that a readonly variable can have different values for different constructors in the same class.

Const vs. Static Readonly

Now we get back to the question Roger originally asked: what is the difference between a variable declared as const and the same variable declared as static readonly?

First, what are the properties of a static readonly variable?

It cannot be changed outside of its declaration or containing class's constructor (due to readonly).

It is part of the type, not part of an instance of that type (due to static).

At first glance this sounds a lot like a constant field, since a constant can only be given a value at its declaration and cannot have that value changed anywhere else. The difference lies in the details.

First, a const variable is not a reference to anything; it is literal value "burned" into the code (using a constant is the true definition of hard coding a value). A static readonly variable is a reference, and consequently a lookup is performed any time this variable is accessed. However, as often happens, the compiler is smarter than you and any supposed performance difference will probably be negated.

But there's another, more subtle difference that we should be aware of. If a const variable exists in Assembly A and is used in Assembly B, when Assembly A gets recompiled with a new value for the const variable Assembly B will still have the previous value until it is also recompiled.

Consider the following class, defined in Assembly A:

public class GeneralData
{
public const int CONSTANT_NUMBER = 6;
}

Imagine that we also have Assembly B, another class library that references Assembly A and uses CONSTANT_NUMBER. Let's say we change this value in Assembly A, like so:

public class GeneralData
{
public const int CONSTANT_NUMBER = 90;
}

We then recompile Assembly A and deploy it, and it will have the new value for CONSTANT_NUMBER. Problem is, Assembly B will still have the value be 6 because it has not been recompiled to include the new value. Here's the original StackOverflow answer explaining this phenomenon.

Summary

Here's what you need to know about using const, static, and readonly:

If you know the value will never, ever, ever change for any reason, use const.

If you're unsure of whether or not the value will change, but you don't want other classes or code to be able to change it, use readonly.

If you need a field to be a property of a type, and not a property of an instance of that type, use static.