How to use readonly vs const vs static in C#
I switched this site’s analytics to
Fathom Analytics to protect
your privacy →
Get $10 OFF your first invoice.
In C#, readonly
, const
, and static
are keywords used to define variables with different behaviors in terms of mutability, memory allocation, and scope.
Understanding their differences is crucial for writing efficient and maintainable code. In this article we'll take a look at each and see how they are used.
1. const (Constant Values)
A const
variable is a compile-time constant, meaning its value must be assigned at declaration and cannot be changed later.
Key Characteristics:
- Must be assigned at declaration.
- Stored in the assembly metadata (not allocated memory at runtime).
- Can only be assigned primitive types,
string
, or enum
values.
- Cannot be modified after compilation.
Example:
public class MathConstants
{
public const double Pi = 3.14159;
}
// Usage:
Console.WriteLine(MathConstants.Pi); // Output: 3.14159
⚠ Limitations:
- Since
const
values are replaced at compile-time, updating a const
in a library requires recompiling all dependent projects.
- Cannot use non-primitive types (e.g., objects, lists).
2. readonly (Runtime Immutable Fields)
A readonly
field allows initialization either at declaration or in the constructor but cannot be modified afterward.
Key Characteristics:
- Can be assigned at declaration or inside a constructor.
- Its value can change during runtime (but only in the constructor).
- Works with all data types, including objects.
- More flexible than
const
since values are resolved at runtime.
Example:
public class Circle
{
public readonly double Radius;
public readonly double Pi = 3.14159;
public Circle(double radius)
{
Radius = radius; // Allowed because it's inside the constructor.
}
}
// Usage:
Circle c = new Circle(5);
Console.WriteLine(c.Radius); // Output: 5
✔ Best for: Values that should remain constant per instance but need to be assigned dynamically at runtime.
3. static (Shared Across All Instances)
A static
variable belongs to the type itself rather than to any instance of the class.
Key Characteristics:
- Shared across all instances of a class.
- Cannot be used with instance constructors.
- Initialized once and persists for the application’s lifetime.
- Can be combined with
readonly
or const
.
Example:
public class GlobalConfig
{
public static string ApplicationName = "MyApp";
public static readonly DateTime StartTime = DateTime.Now;
}
// Usage:
Console.WriteLine(GlobalConfig.ApplicationName); // Output: MyApp
✔ Best for: Global state, caching, configuration values, and utility methods.
Key Differences Summary
Feature |
const |
readonly |
static |
Mutability |
Immutable |
Immutable (after construction) |
Mutable |
When Set |
Compile-time |
Runtime (constructor) |
Runtime |
Memory Usage |
Stored in metadata |
Instance-based |
Type-based (shared) |
Can Use Objects? |
❌ No |
✅ Yes |
✅ Yes |
Can Change After Initialization? |
❌ No |
❌ No (after constructor) |
✅ Yes |
Choosing the Right One:
- Use
const
for fixed, compile-time values that will never change.
- Use
readonly
for immutable values that need runtime initialization.
- Use
static
for class-level data shared across all instances.
Understanding these differences helps you write cleaner, more efficient C# code. Happy coding! 🚀