Difference Between Static, ReadOnly, and Constant in C#

Difference-Between-Constant-and-Readonly-Comparison-in-C#
Difference Between Constant ReadOnly and Static-Readonly in C#

C# Constant, ReadOnly, and Static ReadOnly keywords are relatively common and can be confusing. So, today, we’ll talk about these keywords and try and understand them using examples.

1. C# Constant Keyword

Const: The constant variable is static by default, resulting in creating a single copy. It can be accessed directly by using the class name. Once a constant field’s value has been assigned, it cannot be changed throughout the program.

      • The const variable is static by default. Once a value is assigned to a constant field, the value cannot be changed throughout the program.
      • The const keyword is used to create a constant variable.
      • We can only initialize a constant variable at the time of declaration.
      • Every assembly that uses constants receives a copy of it (every assembly gets a local copy of values).
      • We can declare the constant variable at the class level or inside a method.
      • constant variable creates a single copy and can access globally in the program.
      • We can’t use a const variable with the static keyword.
      • A static variable can modify where a constant variable can never modify.
      • A const field is a compile-time constant.
      • Don’t create a constant to hold the value that we expect to change at any time.
      • The constant variable can be only used to hold fixed value. (Example PI = 3.14)
      • The const is useful in a switch statement as C# doesn’t allow a non-const statement inside the switch
      • We can use the constant keyword with string variable, null reference, or primitive data types like int, long, double, decimal, byte, short, char, float, bool, etc.
      • The const keyword can be used with the access modifiers like public, private, protected, internal, and protected internal.

Eample 1: Constant variable in C#

Example Let’s see whether we can modify the value of a constant variable from within the method or constructor.

const in C#
Const variable in c#

We will get the following compile-time error if we try to change the value of the constant variable.
The left-hand side of an assignment must be a variable, property or indexer

Example2: Const variable in C#

using System;
namespace ConstantDemo
{
   class Constant
    {

     // Initializing const variable.
      public  const double PI = Math.PI;      

    }
    class Program
    {      
        static void Main(string[] args)
        {
            Console.WriteLine($"PI = {Constant.PI}");
            Console.ReadLine();
        }
    }
}

In the above program, the const variable PI is called by the class name without creating an object of the class.

Output of the above Constant program:
Output after executing the above program.

2. ReadOnly keyword in C#

ReadOnly : In C# a  readonly  variable can be initialized at the time of declaration or by Default or parameterized constructor of the same class type. It can’t be reinitialized again inside any type of method or static constructor. The readonly variable is an object-level constant.

      • In C#, readonly keyword is used to create a readonly variable.
      • We can initialize a readonly variable at the declaration time or within the constructor of the same class.
      • We can declare the readonly variable at the class level only.
      • A new copy of the readonly variable is created for each instance of the class.
      • A readonly variable belongs to the object and can access by using the object of the class using the “.” operator.
      • We can use a readonly variable with the static keyword as well.
      • The readonly variables are runtime constant variables.
      • A readonly field cannot be used as ref or out vale (except in a constructor)
      • The value of the readonly field can be changed.
      • In C# the readonly modifier can’t apply to the local variables.
      • The readonly is useful for preventing modification of a variable outside the class.
      • The readonly can be used if the value is unknown at the declaration time.
      • In C# we can use the read-only keyword with any data type ( value type/reference type ).

Note: The read-only variables are useful if we want to have different constant values for the different instances of the class.

Example 1: Readonly variable in C#

using System;
namespace ReadOnlyDemo
{
    class User
    {
        public readonly double id = 123;

        public readonly DateTime currentDate;

        public User()
        {
            currentDate = DateTime.Now;
            // Value can be changed inside the default/parameterized constructor
            id = 456;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
          // readonly int localVariable = 10; 
         // error : The modifier readonly is not valid for this item

            User user = new User();
            Console.WriteLine($"Id = {user.id} CurrentDate :{user.currentDate}");

            Console.ReadLine();
        }
    }
}


output of readonly program in c#
The output of the above ReadOnly program

In the above program, we have reinitialized the read-only variable in the constructor. Now let’s try to reinitialize the variable inside the Main method.

Readonly variable
Trying to reinitialize the read-only variable in the method

In the above image, we can see it doesn’t allow us to reinitialize the read-only variable inside the main method. It displays the following error message.

A read-only field cannot be assigned to (except in a constructor or a variable initializer)

Passing readonly variables as ref/out parameters in the Constructor

As we already, the readonly variables can be initialized inside the default or parameterized constructor.
We can pass readonly variables as ref or out in method parameter if the method is called in the constructor context.

using System;
namespace ReadOnlyDemo
{
    class User
    {
        public readonly int a = 5;

        public readonly int b = 10;   
   
        public User()
        {
            //We can pass ref or out parameter in constructor context only.
            Print(ref a, out b);
        }

        public void Print(ref int a, out int b)
        {
            a = 10;
            b = 20;
            Console.WriteLine($"a: {a} , b: {b}");
        }
    }
    class Program
    {
        public readonly int x = 30;
        public readonly int y = 40;

        static void Main(string[] args)
        {
          
             User user = new User();

             Program p = new Program();
           // user.Print(ref p.x, out p.y);// error:
          // A readonly field cannot be used as ref or out vale (except in a constructor)

            Console.ReadLine();
        }
    }   
}
 //Output: a: 10 , b: 20

We can’t  pass ref or out parameter in the local method otherwise it will throw the following error message: ‘A readonly field cannot be used as ref or out vale (except in a constructor)’

Read the following article to know more about the ref and out keywords.

Difference between Ref and Out keywords in C#

Do not declare readonly to mutable reference types

A mutable type is a type whose instance data can be modified (example: StringBuilder).
As we know that the read-only modifier prevents the field from being modified by a different instance of the reference type.
The ReadOnly does not prevent the instance data of the field from being modified through the reference type.
So, we should not assign read-only to mutable types like collections or arrays because only the reference cannot be changed but the object that holds the values can be changed.

using System;
using System.Collections.Generic;

namespace ReadOnlyDemo
{
    class MyClass
    {
        public readonly List<int> myList;
 
        public MyClass()
        {
            //initializing myList in the constructor

            myList = new List<int>() { 10, 20, 30 };

        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            MyClass obj = new MyClass();

            // Violation of readonly rule
            obj.myList[0] = 5; // value 10 is replaced by 5

            foreach(int item in obj.myList)
            {
                Console.Write(item + "  ");
            }
           // obj.myList = new List<int>(); //Invalid

            Console.ReadLine();
        }
    }

    //Output: 5, 20, 30,
}
The output of the above read-only program:
The output of the above ReadOnly program

In the above example, We can change the values of the ReadOnly list.
When we try to assign the list to the new collection, It will throw a compile-time error because only the reference is immutable not the object itself that holds the value.

3. C# static keyword

In C#,  static  is a keyword that can be applied to classes, variables, methods, properties, constructor and events.

The static modifier is useful to create a single copy of an object (class or data members) to share common data among all the instances.
The static modifier makes a class or data member non-instantiable, that means if we mark a class as static it will not allow us to create an object using the  new  operator.
A class member declared as static can be accessed directly by its class name.

The static keyword in C# is used to define static members which are common to all the objects and not bound to any specific object.

Static variable memory allocation

Static variable in C#
Static variable memory allocation in high-frequency heap

In C#, static and constant data exist for the lifetime of the application, therefore they stored in a high frequency heap and can’t be garbage collected.
A high frequency heap is a kind of loader heap that exists for each AppDomain where all the static data are stored.

C# Static Variables

We can declare a variable as  static  if we want to share the same value throughout all the instances of that class.

Following are some important points about the static variables in C#.

    • A static variable is a class-level variable that can call directly by the class name without creating an instance of that class.
    • A static variable creates only a single copy in the high-frequency heap memory and all the objects of the class share the same copy.
    • Any changes in the value of the static variable will get reflected in all instances where it is used.
    • In C#, we can’t declare static variables at the function level, It doesn’t matter the function is static or non-static.
    • We can’t pass static variables as method arguments.
    • A static variable belongs to the class whereas an instance variable belongs to an object.
    • A static variable can call directly by the class name (Example: MyClass.myVariable).
    • An instance variable can access by the object of the class using the dot .   operator.
    • A static property can get or set the value of a static field of a class only.

Let’s understand the static variable using the below example:

using System;
namespace StaticDemo
{
    public class User
    {  
       // static variable
        public static int userId = 100;

        // instance variable
        public string userName = "Shekh Ali";
    }

    class Program
    {
        static void Main(string[] args)
        {

            //Static members can access directly by the class name.
            Console.WriteLine($"Id= {User.userId}");

            //error, because we can access only static variable by using class name.
            //Console.WriteLine($"{User.name}"); 

            //To access instance variable we have to create object of the class.
            User objUser = new User();

            Console.WriteLine($"Name = {objUser.userName}");

            Console.ReadLine();
        }
    }
}


Static variable result:
The output of the above program.

The following is the pictorial diagram to illustrate how static and nonstatic data members of a class can be accessed in the program.

static variable vs instance variable in C#
Calling static and instance variables.

We can see in the above diagram that the static variable can be accessed by using the class name whereas the instance variable can access by using the object of the class using the “.” operator.

Calling instance variable in the static method

In C# Static variables can be accessed by static and non-static methods whereas instance variables can be accessed by the only non-static methods.

Instance variables belong to the object. To access an instance variable inside the static method we must create an instance of the class.

Example code:

using System;
namespace StaticDemo
{
    public class User
    {
     // static variable
        public static int userId = 100;

        // instance variable
        public string userName = "Shekh Ali";

        //static method
        public static void StaticMethod()
        {
            Console.WriteLine(" Static method ");

            //static members can call by class name
            Console.WriteLine(User.userId);

            //Instance variable will call using the object
            //inside the static method
            User obj = new User();
            Console.WriteLine(obj.userName);
        }

        // Instance method
        public void InstanceMethod()
        {
            Console.WriteLine(" Instance method ");
            //Calling instance variable
            Console.WriteLine($"Name: {userName}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            User.StaticMethod();
            User user = new User();
            user.InstanceMethod();
            Console.ReadLine();
        }
    }
}

C# Static ReadOnly keyword

C# static ReadOnly keyword: The static Readonly variable is very similar to the const variable. We can initialize the static Readonly variable at the compile-time or by using the static constructor only.

The compiler does not have access to the value of the static read-only at the compile time but only at the runtime.

Following is the program for the example.

using System;
namespace StaticReadOnly
{
    public class User
    {   
        // static readonly variable
        public static readonly int id = 100;

        //static constructor
        static User()
        { 
            Console.WriteLine(" Static Constructor ");
            id = 30; //reinitialize the variable
            Console.WriteLine($"Id: {id}");
        }
        //static method
        public static void StaticMethod()
        {
            Console.WriteLine(" Static method ");
            // id = 20; // It will throw error
            Console.WriteLine($"Id: {id}");
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            User.StaticMethod();
            Console.ReadLine();
        }
    }
    /* Output: 
      Static Constructor
       Id: 30
      Static method
       Id: 30
     */
}

In the above program, It allows us to change the value in the static constructor, but we can’t change the value of the static read-only variable in the static method.

If we try to change the value in the static method, it will throw a compile-time error.

A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

Advance – C# Constant keyword : Inspecting library using the ILDASM tool

constant variable creates a single copy and is shared among all the objects. It can access directly by the class name.

The value of the constant fields gets stored inside the .dll or .exe during the compilation time. Which can be seen using the ILDASM tool.

The constant variable in c#

In the above example, we can see that the value of the constant variable ‘PI’ is directly embedded into the IL Code. As we know that constant fields are by default static which can be seen in IL code as well. In C#, The constructors don’t have return types not even void. But after compilation to IL, a constructor has a return type of void. We can see in the above image (.ctor: void())

Use of constant variable into the expression

Constant allows us to use only the constant fields in the expression. We can’t assign an integer or any other data type variable to a constant variable.

using System;
class Program
{
    const int x = 5;

    const int y = 10; 

    const int z = x + y; //Correct, It will work fine.

    int a = 20;
    //const int b = a ; // Compile time error because 'a' is an integer type.

    static void Main(string[] args)
    {
        Console.WriteLine($"z = {z}");

        Console.ReadLine();

    }
}

//Output: z = 15

FAQ

How does Constant differ from ReadOnly in C#?

Both the constant and readonly keywords deal with constant values, however, the value of readonly variables can be set at runtime by the non-static constructors, therefore it can have different values for different objects in the program. The value of constant variables, on the other hand, is common for all the objects and set only during compile time and cannot be changed later.

Can readonly variables be declared at the method level?

No, readonly may only be declared at the class level, not within a method.

Is it possible to declare constant variables at the method level?

Yes, the constant keyword can be declared at the class and method level. constant variables are known as compile-time constant.

Summary:

In this article, we discussed the differences and similarities between const, static, readonly, static readonly keywords in C# with examples.


I hope you got what you were looking for and enjoyed this post. Please share your feedback, questions, or comments if you have any doubts.

Recommended Articles

Leave a Comment