In C#, the keywords static
, const
, readonly
, and static readonly
are frequently used, but they can be confusing. Today, we will discuss these keywords and use some examples to better understand them.
Table of Contents
Difference between static const and readonly in c#
Following is a comparison of the keywords static, readonly, static-readonly, and constant in C#:
Keyword | Description |
---|---|
static | A static field or property is shared among all instances of a class and is stored in the class itself, rather than in each instance. It is initialized when the class is loaded and remains in memory until the program ends. |
readonly | A readonly field or property can only be initialized at the time of declaration or in a Default or parameterized constructor. It cannot be modified after that. It is stored in each instance of the class, so each instance can have a different value for a readonly field. |
const | A const field or property is similar to a readonly field, but the value is evaluated at compile time and is stored in the assembly metadata. It cannot be modified after that. Constants are usually used for values that are known at compile time and do not change, such as mathematical constants or enum values. |
static readonly | In C#, a static readonly field or property is a field or property that is shared among all instances of a class and is stored in the class itself, rather than in each instance. It is initialized when the class is loaded and remains in memory until the program ends. It is also marked as readonly , which means that it can only be initialized at the time of declaration or in a static constructor, and it cannot be modified after that. |
Constant Keyword in C#
A constant variable is a type of variable that has a fixed value that cannot be changed at any point in the program. It is stored in the class itself and is by default static, so there is only one copy of it. You can access it directly by using the class name.
- The
const
keyword is used to create a constant variable that cannot be changed throughout the program. - A constant variable is stored in the class itself, so there is only one copy of it. It can be accessed by all instances of the class and is available globally in the program.
- We can only initialize a constant variable at the time of declaration, and its value cannot be changed after that.
- A constant variable can be declared at the class level or inside a method.
- Every assembly that uses a constant variable receives a copy of it.
- A constant variable cannot be used with the
static
keyword. Astatic
variable can be modified, while a constant variable cannot. - A constant variable is a compile-time constant, which means that its value is evaluated at compile time and is stored in the assembly metadata.
- We should not use a constant variable to hold a value that we expect to change at any time. It is intended for fixed values, such as mathematical constants or enum values.
- The
const
keyword is useful in aswitch
statement because C# does not allow a non-constant expression inside theswitch
. - 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.
Example 1:
In the following code example, we will determine if it is possible to modify the value of a constant variable from within a method or constructor.
If we attempt to change the value of a constant variable, we will receive a compile-time error.
“The left-hand side of an assignment must be a variable, property or indexer“
Example 2:
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, we can call the const variable PI using the class name without creating an instance of the class.
ReadOnly keyword in C#
ReadOnly: In C#, a readonly
variable can be initialized at the time of declaration or in the default or parameterized constructor of the same class type. It cannot be re-initialized inside any type of method or static constructor. A readonly
variable is a constant that is specific to each instance of a class.
- The
readonly
keyword in C# is used to create a readonly variable. - A readonly variable can be initialized at the time of declaration or within the constructor(Default or parameterized constructor) of the same class.
- A readonly variable can only be declared at the class level.
- A new copy of the readonly variable is created for each instance of the class. It can be accessed using the object of the class and the
.
operator. - A readonly variable can be used with the
static
keyword as well. - A readonly variable is a runtime constant, which means that its value is evaluated at runtime.
- A readonly field cannot be used as a
ref
orout
value, except in a constructor. - The value of a readonly field can be changed, but only in a Default or parameterized constructor.
- The
readonly
modifier cannot be applied to local variables. - The
readonly
keyword is useful for preventing the modification of a variable outside the class. - We can use the
readonly
keyword if the value of a variable is unknown at the time of declaration. - The
readonly
keyword can be used with any data type, including value types and reference types.
Note: The read-only variables are useful if we want to have different constant values for the different instances of the same class.
Example 1:
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();
}
}
}
In the above code example, we re-initialized the readonly variable in the constructor. Now, we will try to re-initialize the variable inside the Main
method.
In the above image, we can see that it is not possible to re-initialize the readonly variable inside the Main
method. An error message is displayed.
“A read-only field cannot be assigned to (except in a constructor or a variable initializer)”
Passing readonly variables as ref and out parameters in a constructor.
We already know that readonly variables can be initialized inside the default or parameterized constructor. We can also pass readonly variables as ref
or out
parameters in a method if the method is called in the constructor context.
Example:
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
If we try to pass a ref
or out
parameter in a local method, we will receive an error message:
“A readonly field cannot be used as ref or out value (except in a constructor)”
Post to read more about the ref and out: 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, such as the StringBuilder
class. The readonly
modifier prevents a field from being modified by a different instance of a reference type, but it does not prevent the instance data of the field from being modified through the reference type. Therefore, we should not use the readonly
modifier for mutable types like collections or arrays, because only the reference cannot be changed, but the object that holds the values can be modified.
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,
}
In the above example, we have changed the values of the readonly list. However, if we try to assign the list to a new collection, we will receive a compile-time error because the reference is immutable, but the object itself that holds the value is mutable.
static keyword
In C#, the static keyword can be applied to various elements including classes, variables, methods, properties, constructors, and events. The static modifier creates a single shared copy of an object or data member for all instances to use. It also makes a class or data member non-instantiable, meaning that it cannot be created using the ‘new’ operator. Class members marked as static can be accessed directly using the 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.
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
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 if 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.
Example:
Let’s understand how to use the static variable using the following 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();
}
}
}
The following diagram demonstrates how static and non-static data members of a class can be accessed in a program.
In the above diagram, it can be seen that static variables can be accessed using the class name, while instance variables can be accessed using an object of the class with the dot 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 only non-static methods.
- Instance variables are associated with an object. In order to access an instance variable within a static method, it is necessary to create an instance of the class.
Example:
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();
}
}
}
Static-readonly keyword in C#
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 a static read-only variable at compile time, but only at 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 program mentioned above, it is possible to change the value of a static read-only variable using a static constructor, but it is not possible to modify the value within a 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.
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 a compile-time constants.
Summary:
In this article, we discussed the differences and similarities between const, static, readonly, static readonly keywords in C# with examples.
I hope this information has been helpful and you have found what you were looking for. Please do not hesitate to share any feedback, questions, or comments you may have.
Recommended Articles
-
- Difference between Call by Value and Call by Reference
- C# Monitor class in multithreading with examples
- Multithreading in C#
- 10 Difference between interface and abstract class In C#
- C# Enum | How To Play With Enum in C#?
- Properties In C# with examples
- Generic Delegates in C# With Examples
- Constructors in C# with Examples
- C# Dictionary with Examples
- IEnumerable Interface in C# with examples
- Access Modifiers in C#
- Difference Between Array And ArrayList In C#: Choosing the Right Collection - May 28, 2024
- C# Program to Capitalize the First Character of Each Word in a String - February 21, 2024
- C# Program to Find the Longest Word in a String - February 19, 2024