Skip to content

How to Resolve Error "CS0198: A static readonly field cannot be assigned to" in C#

Learn how to fix the C# compiler error CS0198 by understanding where static readonly fields can be initialized (only in variable initializers or static constructors) and explore solutions like inline assignment, static constructors, or removing readonly for mutable values.

The Compiler Error CS0198 is an assignment restriction error. The message reads: "A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)".

In C#, the static readonly modifiers combine to create a field that belongs to the class itself (not specific objects) and can only be set once during the type's initialization. Any attempt to modify this value later, whether inside a standard method, an instance constructor, or through an external assignment, is blocked by the compiler to guarantee immutability.

This guide explains the lifecycle of static fields and where you are allowed to initialize them.

Understanding Static Readonly Lifecycle

A static readonly field is designed to store data that is calculated once when the application starts (or when the class is first accessed) and never changes afterwards.

There are only two legal places to assign a value to such a field:

  1. Variable Initializer: Directly where the field is declared (e.g., static readonly int X = 5;).
  2. Static Constructor: The special constructor static ClassName() { ... }.

Anywhere else is illegal because the initialization phase has already passed.

Scenario 1: Assignment in Normal Methods

This is the most common mistake. You create a "Configuration" class and try to write a public static void Initialize(int value) method to set the fields.

Example of error:

public class AppConfig
{
    // Declared as static readonly
    public static readonly string ConnectionString;

    // A standard static method (NOT a constructor)
    public static void Initialize(string connStr)
    {
        // ⛔️ Error CS0198: A static readonly field cannot be assigned to 
        // (except in a static constructor or a variable initializer)
        ConnectionString = connStr; 
    }
}

Solution 1: Use a Static Constructor

If the value requires calculation or logic to determine (e.g., reading from a file or environment variable), move that logic into the Static Constructor.

Solution:

public class AppConfig
{
    public static readonly string ConnectionString;

    // ✅ Correct: The static constructor runs once, automatically, 
    // before the class is used. This is a valid place for assignment.
    static AppConfig()
    {
        // Simulate reading from config
        ConnectionString = "Server=MyServer;Database=MyDb;";
    }
}

Solution 2: Use Inline Initialization

If the value is known at compile-time or can be calculated via a simple expression, assign it directly at the point of declaration.

Solution

public class Constants
{
    // ✅ Correct: Inline initialization is valid.
    public static readonly double Pi = 3.14159;
    
    // ✅ Correct: Calling a method inline is also valid.
    public static readonly DateTime StartTime = DateTime.Now;
}

Solution 3: Remove the 'readonly' Modifier

If your application design requires you to set this value after the program has started (for example, via a LoadSettings() method called from Main), then the field is not readonly.

By definition, if it changes based on user input or external timing, it is mutable.

Solution: remove the readonly keyword. To protect the variable from being changed arbitrarily, make the setter private using a Property.

public class AppConfig
{
    // ✅ Correct: Use a Property with a private setter.
    // This allows 'Initialize' to set it, but prevents outside classes from changing it.
    public static string ConnectionString { get; private set; }

    public static void Initialize(string connStr)
    {
        ConnectionString = connStr;
    }
}

Conclusion

CS0198 enforces the immutability of shared data.

  1. Check the location: Are you trying to set the variable inside a method like Init() or Main()?
  2. If it must be immutable: Move the assignment to the static ClassName() constructor.
  3. If it must be set externally: Remove readonly and use a Property with { get; private set; } to maintain control.
Navigation