Click here to Skip to main content
15,895,606 members
Articles / Programming Languages / C#

Constant , Readonly and Static in C#

Rate me:
Please Sign up or sign in to vote.
3.59/5 (7 votes)
6 Apr 2015CPOL4 min read 23.5K   15   5
The article will take you through the three keywords
 
Constantreadonly and static  are mostly used and confused keywords in .NET framework. This article briefly explains about all of the keywords and explains them in the scenarios they can be used in.
 
Constants

As the name suggests the const keyword can be used to set the value of a field at compile time. We need to provide the value to the const field when it is defined. The compiler then saves the constant's value in the assembly's metadata. This means that a constant can be defined only for the primitive type like boolean, char, byte and so on. Constants are always considered static members, not instance members. If we have not provided the value, we get the compile time error “A const field requires a value to be provided”. To support our belief that constant is stored in the metadata I have defined a class with a constant named myConstant as in the following.
       
C#
public class DisplayClass      
{      
   public const int myConstant = 10;   
}  

Now if I look into the metadata of the class using the ildasm I will get the following result:
 
Picture
 
This shows that the value of the constant is stored in the metadata for the class. When the code refers to a constant symbol, the compiler looks up the symbol in the metadata of the assembly that defines the constant, extracts the constant's value and embeds the value in the emitted IL code. This is the reason constants don't require any memory at runtime to be allocated for themselves and since we don't have any memory for the constant that is why these can't be passed as reference.

To show that the value is embedded in the IL code of the application when it refers to an assembly that contains a constant. I have created an assembly as shown below.    
C#
namespace ReferencedAssembly     
{      
   public class DisplayClass   
   {    
      public const int myConstant = 10;    
   }  
} 

Now I will refer to this assembly in my application as shown below.
                       
C#
class Program      
{      
   static void Main(string[] args)      
   {      
     Console.WriteLine("My Constant defined in the library:" + DisplayClass.myConstant);     
   }      
}   <span style="font-family: 'Segoe UI', Arial, sans-serif; font-size: 14px;"</span>

Now if I build and compile my application and check the IL code using the ildasm as shown below, we can see that the myConstant's value is embedded in the code. Even if we delete the referenced assembly, it will not have any impact on my application. 
Picture
 
By now we should have gotten the point that constants can cause some serious versioning problems. If the developer of the Referenced assembly only builds and compiles this assembly and not the application, the application would still refer to the old constant's value. If we want to choose the new value for the constant then in that case we need to recompile our application as well. To choose the latest value we can change it to readonly that I will discuss next. From our discussion we can come to the conclusion that the constant can be used only and only if we are sure that we will not be changing its value in the future.


Fields

Fields can be instance, static and readonly. For a type field (static), the dynamic memory required to hold the field's data is allocated inside the type object that is created when the type is loaded into the AppDomain. That typically happens the first time a method references the type is JIT compiled. Static constructors are used to initialize the values of static members of a class.
For instance fields and the dynamic memory to hold the field is allocated when an instance of the type is constructed.

Since the fields are stored in the dynamic memory, their value can be obtained at runtime only. The versioning problem that we checked in the last section can be resolved by using fields. Apart from that, fields can be any data type, unlike constants that can only be primitive types.

Readonly fields can only be resolved at runtime. That means we can define a value for a value using the constructor for the type in which the field is declared. The verification is done by the compiler that readonly fields are not written to by any method other than the constructor. But please note that reflection can be used to modify a readonly field but that is out of the scope of this article.

Now suppose I use a readonly field in the assembly that I defined earlier.
 
C#
public class DisplayClass     
{      
   public const int myConstant = 10;   
   public readonly int myReadOnly;    
   public DisplayClass()    
   {    
      myReadOnly = 20;    
   }      
} 

And I change my application code as in the following to use the readonly field, now when the application's main method runs, the CLR will load the DLL assembly. That means that my assembly is required at run time and grabs the value of myReadOnly as 20 out of the dynamic memory allocated for it.                       
C#
static void Main(string[] args)      
{      
   Console.WriteLine("My Constant defined in the library:" + DisplayClass.myConstant);      
   Console.ReadLine();      
   DisplayClass display = new DisplayClass();   
   Console.WriteLine("My readonly field defined in the library:" + display.myReadOnly);    
} 
Now suppose I change the value of myReadOnly field to 30, in that case we only need to rebuild only the assembly and not the application. Though we need to keep the point in mind that the assembly is not strongly named and the versioning policy of the application helps the CLR to load this new version.

Kindly share your thoughts about the article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
I have 8 years of experience of mostly developing the .NET windows as well as web applications. Passionate about learning and sharing.

Visit my personal blog to know more about the .NET technology and increase your knowledge about C# and .NET. You can always follow me on twitter @dotnetforall.

Comments and Discussions

 
Generalthank for your share Pin
EUJack4-Jun-15 4:10
EUJack4-Jun-15 4:10 
Generaldefining constant value which is not yet available during initialisation Pin
Peter Huber SG22-Apr-15 17:45
mvaPeter Huber SG22-Apr-15 17:45 
QuestionGood article + some more thoughts about constants Pin
Peter Huber SG19-Apr-15 23:08
mvaPeter Huber SG19-Apr-15 23:08 
QuestionVery nicely for a couple reasons Pin
Michael Breeden9-Apr-15 3:30
Michael Breeden9-Apr-15 3:30 
As developers we do all kinds of advanced stuff, but in all endeavors, one must remember that if you do not stay a master of the basics, you will have problems with the advanced parts.
If you know about mental cybernetics, how the wetware works, you know that memory is far from perfect. One problem is that your memories can become memories of memories. Then they get fuzzy. A software developer must continually refresh their memory of the basics to keep those memories sharp.

AnswerRe: Very nicely for a couple reasons Pin
aarif moh shaikh9-Apr-15 19:04
professionalaarif moh shaikh9-Apr-15 19:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.