The const and readonly keywords in C# are used to declare variables that cannot be changed after they are initialized.
Const variables are initialized at compile time and their value can never change:
… while readonly variables can be initialized at compile time or runtime and their value can be updated but only in a constructor or initializer:
const and readonly in more detail
Let’s look at each one in a little more detail …
Definition: A const field is a compile-time constant. This means its value is known at the time of compilation and remains the same for its entire lifecycle.
Type Limitations: It can only be used with value types (e.g., int, double) and the string type. Custom reference types, arrays, and other data structures cannot be const.
Initialization: It must be initialized at the time of declaration, and the value must be a compile-time constant value (e.g., literal values or other const values). Method calls or runtime evaluations aren’t allowed.
Scope: const members are implicitly static, which means they are associated with the type rather than an instance of the type. You don’t need an instance of the class to access a const member.
Definition: A readonly field can be assigned either at the point of declaration or within the constructor of the class. After that, it cannot be modified.
Type Limitations: There are no type restrictions. It can be used with both value and reference types.
Initialization: It can be assigned a value at the time of declaration or in the constructor(s) of its class. This allows for runtime evaluations and assignments, including method calls.
Scope: readonly members are instance-specific. They can be either static (belonging to the type) or non-static (belonging to an instance).
IL difference between const and readonly
Since consts are compile time constants they are embedded directly into the IL. Click on the image for a larger view in a new window.
Summary of differences between const and readonly in C#
How to choose between const and readonly
If the value is known at compile-time and doesn’t change across different application runs, use const. Ideal for mathematical constants, magic numbers, and enumeration values.
If the value can be determined only at runtime or you want the flexibility of determining the value in the constructor, use readonly.
If you want to ensure the immutability of an object or a complex data type, use readonly.
In general, prefer readonly for more flexibility, especially when working with class-level members, and const for true constant values known at compile time.
Remember to recompile projects which reference consts in other projects
Since const values literally get embedded into the calling codes (not referenced from original source) IL, if we change the value of the const in the original source project we must remember to recompile all referencing projects too. Not doing so will mean the referencing project will have the old const value(s).