What is 'static readonly' in C#? Explained with Examples
Short Answer
In C#, static readonly
is used to declare a field that is shared among all instances of a class and cannot be changed after initialization. The value of a static readonly
field can be assigned either at the time of declaration or within a static constructor. Once set, the value remains constant throughout the program's execution.
Detailed Explanation with Examples
What is static readonly
?
The static readonly
keyword in C# is used to create fields that are:
- Static: Shared among all instances of the class.
- Readonly: Can only be assigned a value once, either at declaration or within a static constructor.
This combination is useful for defining values that should remain constant throughout the program but require runtime initialization or complex logic.
Why Use static readonly
?
static readonly
is useful because:
- Shared Across Instances: Since the field is static, it belongs to the class itself rather than any specific instance.
- Immutable After Initialization: Once assigned, the value cannot be changed, ensuring consistency.
- Runtime Initialization: Unlike
const
, static readonly
fields can be initialized at runtime, making them more flexible.
Example of static readonly
in Action
Let’s look at an example to understand how static readonly
works.
Step 1: Define a Class with static readonly
Fields
Here’s a MyConstants
class with two static readonly
fields: MaxValue
and DefaultName
. The DefaultName
field is initialized in the static constructor.
public class MyConstants
{
// Static readonly field initialized at declaration
public static readonly int MaxValue = 100;
// Static readonly field initialized in the static constructor
public static readonly string DefaultName;
// Static constructor
static MyConstants()
{
DefaultName = "John";
}
}
Step 2: Use the static readonly
Fields
In the Main
method, we access the static readonly
fields directly through the class name.
class Program
{
static void Main()
{
// Access static readonly fields
Console.WriteLine($"Max Value: {MyConstants.MaxValue}"); // Output: Max Value: 100
Console.WriteLine($"Default Name: {MyConstants.DefaultName}"); // Output: Default Name: John
// Error: Cannot modify static readonly fields after initialization
// MyConstants.MaxValue = 200; // Compile-time error
// MyConstants.DefaultName = "Jane"; // Compile-time error
}
}
In this example:
MaxValue
is initialized at declaration.
DefaultName
is initialized in the static constructor.
- Once initialized, neither field can be modified.
Key Points to Remember About static readonly
- Initialization:
- Can be assigned at declaration or within a static constructor.
- Cannot be assigned in non-static methods or constructors.
- Immutability:
- Once assigned, the value cannot be changed.
- Usage:
- Ideal for values that are constant but require runtime initialization or complex logic.
- Comparison with
const
:
const
values are set at compile time and cannot change.
static readonly
values are set at runtime and cannot change after initialization.
Example: Runtime Initialization with static readonly
Let’s say you want to initialize a static readonly
field based on a configuration file or environment variable. Here’s how you can do it:
public class AppSettings
{
public static readonly string ConnectionString;
static AppSettings()
{
// Simulate reading from a configuration file
ConnectionString = Environment.GetEnvironmentVariable("DB_CONNECTION_STRING") ?? "DefaultConnectionString";
}
}
In this example:
- The
ConnectionString
field is initialized in the static constructor.
- The value is determined at runtime based on an environment variable.
Common Mistakes to Avoid
- Attempting to Modify
static readonly
Fields:
- Using Non-Static Constructors:
Real-World Use Case: Application Constants
Imagine you’re building an application where certain settings (e.g., API keys, connection strings) need to be constant but are determined at runtime. You can use static readonly
fields to store these values.
public class AppConfig
{
public static readonly string ApiKey;
public static readonly string LogLevel;
static AppConfig()
{
// Initialize values from environment variables or configuration files
ApiKey = Environment.GetEnvironmentVariable("API_KEY") ?? "DefaultApiKey";
LogLevel = Environment.GetEnvironmentVariable("LOG_LEVEL") ?? "Info";
}
}
Here's another example that demonstrates an error when attempting to assign a value to a 'readonly' variable in a different method..
As shown in the image below, a variable named 'ProductionYear' is declared as static readonly. While we can assign a value to this variable within the static constructor, any attempt to assign it within other methods or events will result in a compile-time error.
Final Thoughts
static readonly
is a powerful feature in C# that allows you to define constant values that are shared across all instances of a class and cannot be changed after initialization. It’s particularly useful for values that require runtime initialization or complex logic. By understanding how and when to use static readonly
, you can write more robust and maintainable code.