Skip to main content

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

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—inside a standard method, an instance constructor, or 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.

note

Static vs. Instance Readonly:

  • readonly int x; (Instance): Can be assigned in any instance constructor.
  • static readonly int x; (Static): Can only be assigned in the static constructor.

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;";
}
}
warning

You cannot pass parameters to a static constructor (see CS0132). If you absolutely need to pass external data to initialize the field, you cannot use readonly. See Solution 3.

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.