C# > Core C# > Variables and Data Types > Constants and Readonly Fields

Constants and Readonly Fields in C#

This code snippet demonstrates the use of const and readonly keywords in C#. These are used to create fields whose values cannot be changed after initialization, but they differ in when and how they are initialized. Understanding these differences is crucial for writing robust and efficient C# code.

Constants (const)

Constants are declared using the const keyword. Their values must be known at compile time and cannot be changed later. Constants are implicitly static, meaning they belong to the type itself, not to any particular instance of the type. You access them directly through the class name (e.g., ConstantsExample.PI). They are stored in metadata, so accessing them does not require accessing memory occupied by object. It enhances performance. A constant value should only be used where the value will never change.

public class ConstantsExample
{
    public const double PI = 3.14159;
    public const string CompanyName = "Acme Corp";

    public void PrintCircleArea(double radius)
    {
        double area = PI * radius * radius;
        Console.WriteLine("Area: " + area);
        Console.WriteLine("Company Name: " + CompanyName);
    }
}

Readonly Fields (readonly)

Readonly fields are declared using the readonly keyword. Their values can be assigned only in the field's declaration or within the constructor of the class. Unlike constants, readonly fields can be assigned values at runtime. They are not implicitly static. They can be instance fields or static fields. A readonly field can have different values for different instances of the same class. Readonly allows for deferred initialization, providing more flexibility compared to const. Readonly is appropriate for values determined at runtime but remain constant for the lifetime of the object or application domain.

public class ReadonlyExample
{
    public readonly DateTime CreationDate;
    public readonly string MachineName;

    public ReadonlyExample()
    {
        CreationDate = DateTime.Now;
        MachineName = Environment.MachineName;
    }

    public ReadonlyExample(DateTime specificDate)
    {
        CreationDate = specificDate;
        MachineName = Environment.MachineName; //Can change
    }

    public void PrintInfo()
    {
        Console.WriteLine("Creation Date: " + CreationDate);
        Console.WriteLine("Machine Name: " + MachineName);
    }
}

Concepts Behind the Snippet

The core concepts demonstrated here are immutability and compile-time vs. runtime evaluation. const provides compile-time immutability, ensuring the value is known before the application runs. readonly provides runtime immutability, allowing values to be set during object creation but not modified thereafter. These features are used to ensure data integrity and prevent unintentional modification of critical values. Values that are immutable can be more reliable in multi-threaded environment or if the values is something shared across multiple instances.

Real-Life Use Case

const is well-suited for values that are truly constant, like mathematical constants (PI), configuration settings that are fixed, or error codes. For example, a game might define constant level IDs. readonly is used for values that are determined at runtime but should not change after initialization. Examples include: a user's ID assigned upon account creation, the date an object was created, or a configuration setting loaded from a file at startup.

Best Practices

Use const when the value is known at compile time and will never change. Use readonly when the value is determined at runtime but should remain constant for the lifetime of the object. Avoid using const for values that might change in the future, even if they are currently constant. Favor readonly over mutable fields when possible to promote immutability and prevent unintended side effects. When declaring constants, use descriptive names that clearly indicate the purpose of the constant.

Interview Tip

Be prepared to explain the difference between const and readonly. Key differences include: when the value is assigned (compile-time vs. runtime), whether it's implicitly static (const is), and whether it can be assigned in the constructor (readonly can). Also, be ready to discuss the benefits of immutability in general.

When to Use Them

Use const for values like: Mathematical constants (e.g., PI), application version numbers, default configuration values, and predefined error codes. Use readonly for: IDs generated at runtime (e.g., user ID), timestamps of object creation, connection strings loaded from configuration, and dependencies injected during object creation.

Memory Footprint

const values are typically inlined directly into the code where they are used, effectively replacing the variable with the value during compilation. This can result in smaller compiled code size and potentially faster execution. readonly fields consume memory like regular fields of the class. Each instance of the class will have its own copy of the readonly field. Static readonly fields are stored once per application domain.

Alternatives

Alternatives to const and readonly include using properties with a private setter to restrict modification after initialization. However, this approach does not provide the same level of compile-time safety as const or the runtime immutability guarantee of readonly. For values that might change during the application's lifetime, consider using a configuration management system or an immutable data structure. You could also use a library that provides immutable collections or data structures.

Pros of const and readonly

const: Compile-time safety, inlining for performance, guaranteed immutability. readonly: Runtime immutability, initialization at runtime, flexibility in assignment (constructor), supports different values per instance.

Cons of const and readonly

const: Value must be known at compile time, cannot be different for different instances, changes to the value require recompilation. readonly: Value is only immutable after construction, not at compile time, requires memory allocation for the field in each instance.

FAQ

  • What happens if I try to change a const variable?

    The compiler will generate an error. const variables are compile-time constants and cannot be modified after they are declared and initialized.
  • Can a readonly field be modified using reflection?

    Yes, readonly fields can be modified using reflection, although it's generally discouraged as it violates the intended immutability. Reflection bypasses normal access restrictions.
  • Can I use const inside a method?

    No, const is only allowed at class or struct level. It is used to define the value of a class member and its life cycle is throughout application.