C#: Difference between Const and Readonly
Const vs Readonly
The main difference between const and readonly keywords in C# is that const need to be defined at the time of assignment, while readonly field can be defined at runtime. Const's are implicitly static, while readonly values don't have to be static.
Moreover, const and readonly have different behavior when working with assemblies. Constants are copied into every assembly that uses them, while readonly fields are shared across assemblies.
Constants don't have memory allocation during runtime because they are embedded into the IL code. On the other hand, readonly fields allocate memory because they are stored in the loader heap.
Const | Readonly |
---|---|
Must be defined at compile time | Can be defined at compile time or runtime |
Implicitly static | Instance-level or static |
Copied across assemblies | Shared across assemblies |
Do not allocate memory | Allocate memory |
Assignment
Unlike with constants, we can determine the value of a readonly field at runtime but only within the scope of a constructor.
public class App
{
public readonly int VERSION = 5;
public App()
{
VERSION = 6; // This works!
}
public void UpdateVersion()
{
VERSION = 7; // This does not work!
}
}
On the other hand, constants cannot change once defined. For example:
public class App
{
public const int VERSION = 5;
public App()
{
VERSION = 6;
}
}
If we try to run the code above, we will get the error:
Error: (6,9): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
Assemblies
Const and readonly also have different behavior when working with assemblies. A static readonly field is shared across assemblies, while const value is baked into each assembly.
For example, lets say we have assembly A and assembly B.
Assembly A defines the constant:
public const int PRODUCTS_PER_PAGE = 10;
Both assembly A and assembly B use the same constant.
If we change the constant above to be 15
, we need to recompile both assemblies.
On the other hand, with static readonly field, we would only need to recompile the assembly A.
Because of sharing across assemblies, static readonly
properties are a great to speed up string comparison, as I demonstrated in my string enum alternatives article.
Use const
for values that you truly know will never change. For example, Math PI value.
FAQ on const vs readonly differences
Can local variable be readonly?
A local variable cannot be readonly. The readonly keyword can only be used on fields, not on local variables.
How to fix "A readonly field cannot be assigned to" error?
If you try to change the value of a readonly field outside of the constructor, you will get the following error:
error CS0191: A readonly field cannot be assigned to (except in a constructor or init-only setter of the type in which the field is defined or a variable initializer)
To fix "A readonly field cannot be assigned to" error, remove the readonly
keyword from your field.
But be careful because doing so will impact encapsulation. Your field will become accessible from outside the class. If you don't want to do that, a better approach would be to keep the readonly
modifier and to change the design so the value can only be changed from within the constructor.
Before:
public class App
{
public int VERSION = 5;
public App()
{
}
public void UpdateVersion(int version)
{
VERSION = version;
}
}
After:
public class App
{
public readonly int VERSION = 5;
public App(int version)
{
VERSION = version;
}
public void UpdateVersion(int version)
{
VERSION = version;
}
}
Is it safe to use readonly with .NET dependency injection?
Yes, we can use readonly fields with .NET dependency injection.
Here's an example of such behavior with dependency injection in .NET:
class OrderService {
private readonly CartService _cartService;
public OrderService(CartService cartService) {
_cartService = cartService;
}
}
The OrderService above has a dependency of CartService which is unknown until the runtime. We use private readonly field for the CartService because it's passed via OrderService constructor.
Josip Miskovic is a software developer at Americaneagle.com. Josip has 10+ years in experience in developing web applications, mobile apps, and games.
Read more posts →I've used these principles to increase my earnings by 63% in two years. So can you.
Dive into my 7 actionable steps to elevate your career.