Author avatar

Dániel Szabó

Const vs. Readonly vs. Static

Dániel Szabó

  • Sep 16, 2019
  • 6 Min read
  • 262 Views
  • Sep 16, 2019
  • 6 Min read
  • 262 Views
Languages Frameworks and Tools
C#

Introduction

C# facilitates keywords like const, readonly, and static readonly which can be confusing at a time when you need them the most. Very small differences separate those three keywords that result in totally different execution flow in your applications. This guide will walk you through the nifty details and what you need to know to properly utilize these keywords in your applications.

Constant

The const keyword converts nothing more but a constant. The specialty of these variables is that they need to have a value at compile time and, by default, they are static. This default value means that a single copy of the variable is created and shared among all objects. In case you are using this context via class, you can access them through the name of the class. It is also important that, for complex applications where the solution is referenced, get a local copy of the constant across assemblies.

As an example, take a look at a constant.

1
const string myConstant;
csharp

By default, this would throw a compile time error because you are expected to provide a value to the constant before compilation. The correct form would be:

1
const string myConstant = "Constants are cool!"
csharp

An exception to this is when you define a constant in a function.

1
2
3
4
5
static string TestConst()
{
	const string solved = "This is a viable solution!";
	return solved;
}
csharp

Call this function with the following statement:

1
Console.WriteLine($"The constant returned was: {TestConst()}");
csharp

The above gives us the following console output. Note the f-string based string interpolation that allows function calls.

1
The constant returned was: This is a viable solution!
bash

Readonly

The readonly keyword is a special modifier which bears significant resemblance to the const keyword. It can be used on fields, but not on local variables. These fields can either be initialized when declared or at the constructor of our object. This keyword ensures that a variable instance or property of an object cannot be modified after initialization, and such attempts will result in an exception. While const is initialized at compile time, readonly keyword allow the variable to be initialized either at compile time or runtime.

Both initializations are fine, from the compiler side.

1
2
3
public readonly string compileTime = "Whateeeva";

public readonly string runTime;
csharp

The compileTime variable tells you this is initialized beforehand. No exception is thrown, the runTime indicates that this variable will have its value initialized with the class' constructor.

Let's take an example of that.

1
2
3
4
5
6
class Student 
{
	public readonly string FullName;
	public Student(string name) 
		{ FullName = name; }
}
csharp

This definition holds the FullName property of the class which is initialized at runtime, but the compilation still succeeds due to the nature of the readonly keyword.

Let's instantiate our class and print the FullName.

1
2
3
Student Daniel = new Student( "Szabó Dániel Ernő");

Console.WriteLine($"The full name of the student is : {Daniel.FullName}");
csharp

If we did everything correctly, the following output should be visible on our console.

1
The full name of the student is : Szabó Dániel Ernő
bash

Core Difference

At the highest level, if we want to differentiate the readonly and const keywords. We could say that the difference lies in when the value of the variable is known throughout the lifecycle of the application. For the readonly keyword, the latest value is known by the runtime. For the const keyword, the value must be known by compile time. The common of these two keywords is that they both cover immutable data types, meaning the value cannot change throughout the life of the application.

For the const keyword, the variable marked as such is placed by the compiler in the assembly metadata that defines the constant and metadata and embeds the value into the IL code after initialization. This means that there is no memory allocation for constants during runtime. Under the hood, the readonly value is not a constant; it's stored in the loader heap, which is a memory type that cannot be allocated until the type is loaded. The readonly fields are stored in dynamic memory, the values are accessible only at runtime.

Despite being very similar, these keywords use different binary versioning. When an expression references a specific constant, the compiler embeds the value at compile-time. This means that. if the value is used in a different assembly, the original needs to be updated and the value changed. The changes in the assembly are not reflected until it is recompiled. When an expression references a readonly field, the value is not obtained until runtime. Change in the value is reflected immediately, the assembly does not need to be recompiled.

Conclusion

The idea behind both keywords is the same. We would like to mark a variable to hold its value during the execution of the application and not allow modification. The first difference is the timeslot which initializes the const or readonly variables. The first, const, is initialized during compile-time and the latter, readonly, initialized is by the latest run-time. The second difference is that readonly can only be initialized at the class-level. Another important difference is that const variables can be referenced through "ClassName.VariableName", while readonly can be referenced through "InstanceName.VariableName". I have introduced the differences and similarities to the best of my abilities and I hope you found what you were looking for.

0