Const
The const keyword declares constants – values that won’t change throughout the lifetime of a program. Constants are initialized on declaration and are static by default. At compile time, the compiler replaces all usages with the constant’s literal value.
const int INCHES_IN_A_FOOT = 12;
const int CM_IN_A_METRE;
//Fails because it's
// not initialized on declaration
The constant-to-literal substitution has a downside – all external consumers of a constant have to be rebuilt if it changes. For example, should pi be a const or readonly? Using const should be fine however if precision requirements change often, then using readonly removes the need for excessive downstream re-compilation.
It is semantically correct to use the const qualifier for reference types but this serves no purpose. Constants have to be initialized at declaration and only null values are allowed for reference types (strings are the only exception). Moreover after such null initializations, the constants cannot be changed anymore. What’s the use of a null const?
const List intList = new List{1,2,3};
//fails, only null values are
//allowed for const reference types
const List intList2 = null;
//compiles but useless
// as it cannot be changed anymore
Readonly
Unlike constants which MUST have values declared at initialization, readonly values can be set at declaration or in the constructor. Once set, readonly values cannot be changed anymore; such attempts will result in exceptions. Since constructors can be overloaded, a readonly value is determined by its construction path.
using System;
public class Test
{
public readonly int rdOnly = 3;
public Test(int rdVal)
{
rdOnly = rdVal;
Console.WriteLine(rdOnly);
}
public Test()
{
rdOnly = 5;
Console.WriteLine(rdOnly);
}
public Test(string s)
{
Console.WriteLine(s);
Console.WriteLine(rdOnly);
}
public static void Main()
{
Test test1 = new Test(100);
//100
Test test2 = new Test();
//5
Test test3 = new Test("Hello");
//3
test3.rdOnly = 2000;
// compile error
}
}
If there is any chance that a ‘constant’ value might change and a lot of assemblies use it; it’s better to use readonly – this removes the need for re-compiling a lot of modules downstream.
Differences between const and readonly
- Const values are always implicitly static while readonly values are not.
- Const values have to be initialized on declaration while readonly values can be set on declaration or in the constructor – the only rule is that the value must be set before the constructor exits.
- On compilation, all const values are replaced with their literal values globally while readonly usages contain a reference to the sole declaration.
Caution! Usage Gotcha
Marking a reference type as readonly ‘freezes’ the reference and not the referenced value. The readonly reference cannot be replaced by another however you are free to change the contents of the reference object!
public class ReadonlyCheck
{
readonly Point rdOnlyP
= new Point(0,0);
public ReadonlyCheck()
{
rdOnlyP.xcoord = 5;
//succeeds
rdOnlyP = new Point(1,1);
//fails
}
}
Conclusion
This post explained the difference between the readonly and const keywords in C# and explained when and how to use them. Here are a couple more posts you might enjoy:
1. Understanding Tail Recursion
One thought on “C# Const vs Readonly”