Home > Tutorial > csharp > C#-10 differences between Constant, ReadOnly & Static ReadOnly in C#

C#-10 differences between Constant, ReadOnly & Static ReadOnly in C#

ReadOnly and Constant in C#

 

Constant modifier in C# makes fields or locals constant.ReadOnly applies to fields in C#, value is constant after initialization.Static ReadOnly makes ReadOnly field class member.(Can be accessed through class name)

Please go through the summary of differences between constant and readonly then I will try to explain each point after that.

10 main Difference between Constant vs Readonly fields in C#:

 

Constant in C#Readonly in C#
const keyword can be applied to fields or local variablesreadonly keyword applies only to fields not local variables
We must assign constant field at the time of declation onlyWe can assign readonly field at the time of declaration or in constructor,not in any other methods.
No Memory Allocated Because constant value embedded in IL code itself after compilationdynamic memory allocated for readonly fields and we can get the value at run time.
Constants in C# are by default static.Can be accessed only through class nameReadonly belongs to the object created so accessed through only through instance of class. To make it class member we need to add static keyword before readonly.
We can declare following built in (primitive types) datatypes as constant Boolean,Char, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Single, Double, Decimal and also string.Same as Constant
The value is constant (as it is belongs to class)The value may be different depending upon constructor used (as it belongs to object of the class)
If we want to declare constant for someclass (non-primitive types) we should assign it to null which as of no use.If you declare a non-primitive types (reference type) as readonly only reference is immutable not the object it contains.(see the example below)
Do not use const field that might change over the time it leads to dll version problem
(see the example)
As the value obtained at run time there is no dll versioning problem with static readonly fields
Const field can not be passed as ref or out parameterWe can pass readonly field as ref or out parameters in the constructor context.

 

ReadOnly and Constant in C#
ReadOnly and Constant in C#

 

Constant field or local in C#:

 

We will use keyword “const” to declare Constant fields or locals in C#.

Whenever you are defining a constant field its value must be assigned at the time of declaration itself, after that we cannot change its value. Go through the following example to understand it

        
        Public class Program
        {
           const int fieldConstant = 10; //Field

           static void Main(string[] args)
           {
             const int X = 10, Y = 50; //Correct //Local Variable
             const int Z = X + Y;      //Correct
             const int A = X + GettheValue(); // Error
           } 
           public static int GettheValue()
           {
             const int localx=10;
             return 10;
           }
        }

 

The first two lines will works without any errors because X,Y,Z field values are evaluated at the time of compile time itself. But in 3rd line we declared a variable ‘A’ as constant and trying to evaluate its value at runtime using GettheValue() method.The line will not execute because constants variables must be assigned at the time of compile time itself.

A Field in C# is a variable that is declared directly in a class or struct

In the above example fieldConstant is a field because its directly declared inside program class.

And we can declare local variables as const as shown in above GetTheValue() method.

The following built in value types can be declared as Constants: int, long, char, float, double, decimal, bool, byte, short, string variable as constant.

And we can assign non-primitive types to null to define a constant.But it’s useless to declare a constant reference type which is assigned to null.

            const string constantString = "Hi Iam Constant"; //Correct
            const Program program = new Program(); //Error
            const Program program1 = null; //Correct

 

You cannot declare a constant variable as static because constants are considered as static members by default.

            ReadonlyConstant r1=new ReadonlyConstant();// Please see the below code for class declaration

            Console.WriteLine(r1.ynumber);              //Error
            Console.WriteLine(ReadonlyConstant.ynumber);//Correct

 

As the constant variable by default static, you cannot access it from the instance of the class. And we cannot pass const values as ref or out params.

 

ReadOnly Field in C#:

 

We can declare fields as Readonly in C# not local variables.

ReadOnly fields can be initialized at the time of declaration or only within the constructor which is called only once at the time of object creation, not in any other method.

    public class ReadonlyConstant
    {
        
        public const int numberOfDays = 7; //Field
        public readonly double PI=3.14;             //inline intialization
        
        public readonly int znumber;
        public readonly List<int> readonlyList;

        public ReadonlyConstant()
        {
            znumber= 50;//Constructor initialization            
        }

        public ReadonlyConstant(int x)
        {
             znumber=100;
        }
        
        public NormalMethod()
        {
            //readonly int i=0; This is wrong
        }
    }

 

And the value may be different depending upon the constructor used. i.e., readonly field belongs to object of the class.

Please read the further article about readonly field to understand it further.

The curious case of Readonly field in C#

Now we will go through the differences between constant and readonly fields, As mentioned in the second point for constant fields no memory allocated and the value directly embedded in IL code. please see the below picture of IL code. (Few differences explained in above post)

Constant-Readonly-IL-Code
Constant-Readonly-IL-Code

I used resharper tool to see Intermediate Language(IL) code of above sample program (ReadonlyConstant.cs)

As you can see the IL code of const field numberOfdays value (7) directly embedded into IL code. Where as the readonly field piValue is displayed as piValue i.e., the value can be obtained at run time.

This leads to versioning problem.

Versioning problem of the Constant field in C#:

 

I compiled above sample program as a class library(A) and used it in another project (in B) as a reference.  Now see the generated IL code of project B

Readonly and Constant field difference at IL Code
Readonly-Constant-IL-Code

And Even in project B IL code, the value of constant field numberofdays embedded in IL code. Now the problem is, in the source (in A ReadonlyConstant.cs library) the constant field (numberOfdays )value changed to 5 and compiled and generated a new dll.

But this new value of the constant field does not affect in project B until unless we compile the project. After compilation the new constant field value will be embedded in IL code of project B.

To overcome this problem we will use static readonly fields.

Static Readonly field in C#:

 

As the readonly field value is different depending upon the constructor used (As explained in the above article). To make it class member (static member) and unique to the class, we will add static keyword before the variable as shown below.

public class ReadonlyStatic
{
   public static readonly string x = "Hi";
   public static readonly string y;

   public ReadonlyStatic()
   {
     //y = "Hello"; This is wrong
   }

   static ReadonlyStatic()
   {
      y = "Hello";
   }
}

Now we can use it as constant across the class will overcome the dll version problem with constant variables.There may be some performance issues but no need to build the destination project as the value can be obtained at run time.

As shown in the above example we can assign static readonly fields at the time of declaration or in static constructor only.

remaining differences I explained in above readonly article (as the post is becoming large I thought of splitting it two)

Readonly vs Static Readonly in C#:

 

Following are the main differences between readonly and static readonly fields in C#.

Readonly in C#Static Readonly in C#
Can be assigned at the time of declaration or constructorCan be assigned at the time of declaration or static constructor
Value may be different depending upon the constructor usedValue will be constant after the initialization

 

When to use Constant and readonly in C#

 

Use constant when the value is absolute constant that won’t change over the time. For example Number of days in a week is 7. This is always constant. and when in doubt use static readonly to avoid the dll versioning problem.

As the constant value embedded inside IL Use constant modifier for absolute constants to gain performance benefits.

And as explained in the above readonly article if we want to use different constant values for a different instance of the class (or objects) use readonly.

I hope you understand the key differences between constant and readonly modifiers in C#.If so share with your friends and If you have any doubts please feel free to comment below.

Read my articles

Understand delegates and events in c#

Difference between Ref and out parameters in C#

Happy Coding….!

Wait before leaving. why can’t you follow me on twitter or be a friend on Facebook or googlePlus or linkedn to get in touch me. or join our mailing list

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Arunkumar Gudelli

I am “One among a million” Software engineers of India.
I write beautiful markup.I make the Web useful.
You can connect me via @twitter or @facebook or Google+ or e-mail.

http://www.arungudelli.com

7 thoughts on “C#-10 differences between Constant, ReadOnly & Static ReadOnly in C#

  1. ‘Constructor`, not `Constructer`.
    ‘Primitive’, not ‘Premitive’.

    Also does the 5th row in the first table imply that readonly fields can only be of primitive types too?

  2. It is not clear to me from your series of articles that you understand the purpose of readonly. It is a signal to the clr as to how to handle processor caching, particularly in a multi-threaded application. It has the opposite effect of volatile which tells clr to force a processor to fetch the value from memory every time it is accessed instead of relying on the local cache for the value. With readonly you are telling the clr that the value will never change during the lifetime of the instance or the AppDomain in the case of a static field and therefore it can be lazy and used cached values safely.

    Yes, the readonly field may reference mutable objects, but that may be what you want. For example, you could have a readonly field of ConcurrentDictionary and you should have it as readonly for full thread safety.

    Are good practice, you should use readonly wherever practical initially. If you find that you need a mutable field later, you can remove the readonly modifier. Note that after much complaining, Microsoft finally added automatic properties with readonly backing fields by allowing you to assign to an automatic with only get defined at the same time you could with an explicit readonly field (in the constructor or as a default value to the definition).

  3. Your article is great. I studied it 98%, to be frank. It was really great. The way you expressed your thought process behind this C# concept is really good. But for the rest of the 2%, I thought “Oh, this is too big article. Do I need to read it? Points are repetitive. “. So, it would be better if it’s concise and precise. Great job, brother. I am very new to C# and also to programming. I am like a baby who can’t walk. I need help from guys like you to learn a lot. Will you help me, brother?

Lets have chat