"static readonly" vs. "const" in c#

In c#, when you want to declare a field holding a specific, static value for all instances of a type, there are two ways to achieve this: either you declare the field static readonly, or you declare a const. But what is the difference between them?

Take the following code:

class Sample
{
   public const int TheConst = 1;
   public static readonly int TheStaticReadonly = 1;
}

Looking at the IL code, the two members generate the following:
.field public static literal int32 TheConst = int32(0x00000001)
.field public static initonly int32 TheStaticReadonly

As we can see, there are two concrete differences:

  • TheConst is declared as a literal, and has an int32 value assigned to it
  • TheStaticReadonly is declared as a initonly, and has no value assigned to it

The assignment of TheStaticReadonly has been moved to the static constructor. This means that the code sample above generates identical byte code as the following:

class Sample
{
    public const int TheConst = 1;
    public static readonly int TheStaticReadonly;

    static Sample()
    {
        TheStaticReadonly = 1;
    }
}

That means that if a type has a const declared, its value is known as compile time, while the value of a static readonly field cannot be known at compile time. This is a small, but important difference. For instance, it means that you cannot use the value of a static readonly field anywhere in your code where a constant value is expected:

int n = 1;
switch (n)
{
    case Sample.TheConst:
        {
            break;
        }
    case Sample.TheStaticReadonly: // compiler error CS0150 ("A constant value is expected") 
        {
            break;
        }
}