Detailed Explanation with Examples
What is readonly?
The readonly keyword in C# is used to create fields that can only be assigned a value once—either at the time of declaration or within the constructor of the class. After initialization, the value of a readonly field cannot be modified. This makes readonly fields ideal for values that should remain constant throughout the lifetime of an object but are not known until runtime.
Example of readonly in Action
Let’s look at an example to understand how readonly works.
Step 1: Define a Class with readonly Fields
Here’s a Car class with three readonly fields: Make, Model, and ProductionYear. These fields are initialized in the constructor.
public class Car
{
public readonly string Make;
public readonly string Model;
public readonly int ProductionYear;
// Constructor to initialize readonly fields
public Car(string make, string model, int productionYear)
{
Make = make;
Model = model;
ProductionYear = productionYear;
}
// Method to display car details
public void DisplayCarDetails()
{
Console.WriteLine($"Make: {Make}, Model: {Model}, Production Year: {ProductionYear}");
}
}
Step 2: Use the readonly Fields
In the Main method, we create two Car objects and initialize their readonly fields. Once initialized, these fields cannot be changed.
class Program
{
static void Main()
{
// Create two Car objects
Car car1 = new Car("Toyota", "Camry", 2022);
Car car2 = new Car("Honda", "Civic", 2023);
// Display car details
car1.DisplayCarDetails(); // Output: Make: Toyota, Model: Camry, Production Year: 2022
car2.DisplayCarDetails(); // Output: Make: Honda, Model: Civic, Production Year: 2023
// Error: Cannot modify readonly fields after initialization
// car1.ProductionYear = 2024; // This will cause a compile-time error
}
}
In this example:
- The
Make, Model, and ProductionYear fields are initialized in the constructor.
- Once initialized, these fields cannot be modified, ensuring their values remain constant for the lifetime of the object.
What is the Difference Between const and readonly?
While both const and readonly are used to create fields with constant values, they have key differences:
| Feature |
const |
readonly |
| Value Assignment |
Must be assigned at declaration. |
Can be assigned at declaration or in the constructor. |
| When Value is Set |
Compile-time. |
Runtime (during object creation). |
| Scope |
Static by default. Accessed through the class name. |
Can be static or instance-specific. |
| Usage |
Used for values known at compile time (e.g., mathematical constants). |
Used for values known at runtime (e.g., object-specific settings). |
| Modification |
Cannot be changed after declaration. |
Cannot be changed after initialization. |
Example: const vs readonly
Let’s compare const and readonly in a practical example.
Step 1: Define a Class with const and readonly Fields
Here’s a Settings class with a const field (Pi) and a readonly field (AppVersion).
public class Settings
{
// const field (must be assigned at declaration)
public const double Pi = 3.14159;
// readonly field (can be assigned in the constructor)
public readonly string AppVersion;
// Constructor to initialize readonly field
public Settings(string appVersion)
{
AppVersion = appVersion;
}
// Method to display settings
public void DisplaySettings()
{
Console.WriteLine($"Pi: {Pi}, App Version: {AppVersion}");
}
}
Step 2: Use const and readonly Fields
In the Main method, we create an instance of the Settings class and display the values of the const and readonly fields.
class Program
{
static void Main()
{
// Create a Settings object
Settings settings = new Settings("1.0.0");
// Display settings
settings.DisplaySettings(); // Output: Pi: 3.14159, App Version: 1.0.0
// Access const field directly through the class name
Console.WriteLine($"Pi value: {Settings.Pi}"); // Output: Pi value: 3.14159
// Error: Cannot modify const or readonly fields
// Settings.Pi = 3.14; // Compile-time error
// settings.AppVersion = "2.0.0"; // Compile-time error
}
}
In this example:
- The
const field Pi is assigned at declaration and cannot be changed.
- The
readonly field AppVersion is assigned in the constructor and cannot be changed after initialization.
Key Points to Remember
const:
- Used for values that are known at compile time and never change.
- Must be assigned at declaration.
- Accessed through the class name (static by default).
readonly:
- Used for values that are known at runtime and should not change after initialization.
- Can be assigned at declaration or in the constructor.
- Can be instance-specific or static.
- When to Use:
- Use
const for fixed values like mathematical constants (e.g., Pi).
- Use
readonly for values that depend on runtime data (e.g., configuration settings).
Real-World Use Case: Configuration Settings
Imagine you’re building an application where the version number is set at runtime based on a configuration file. You can use a readonly field to store the version number, ensuring it remains constant after initialization.
public class AppConfig
{
public readonly string Version;
public AppConfig(string version)
{
Version = version;
}
public void DisplayVersion()
{
Console.WriteLine($"App Version: {Version}");
}
}