Skip to main content

How to Resolve Error "CS0150: A constant value is expected" in C#

The Compiler Error CS0150 is a Compile-Time vs. Runtime error. The message reads: "A constant value is expected".

In C#, specific language constructs require values that are fully known and calculated before the program runs (at compile-time). If you try to use a variable, a method call, or a static readonly field (which are resolved at runtime) in these specific places, the compiler generates CS0150.

This guide explains where constant values are strictly required and how to ensure your data meets that requirement.

Understanding Constants vs. Readonly

To fix this error, you must distinguish between:

  • Constant (const): The value is hardcoded into the DLL. It effectively replaces the variable name with the literal value (e.g., 5) during compilation.
  • Read-Only (static readonly): The value is calculated when the program starts.

CS0150 occurs when the compiler needs a const, but you gave it a readonly variable or a standard variable.

Scenario 1: Switch Case Labels (Most Common)

Standard switch statements (specifically the case labels) require constant values to build the jump table optimization. You cannot use a variable as a case label.

Example of error

Using a static readonly field or a standard variable in a case.

public class Menu
{
// ⚠️ 'static readonly' is evaluated at RUNTIME, not compile-time.
public static readonly int OptionExit = 9;

public void SelectOption(int input)
{
switch (input)
{
case 1:
Console.WriteLine("Start");
break;

// ⛔️ Error CS0150: A constant value is expected
// The compiler cannot build the switch logic because
// it doesn't know what 'OptionExit' is yet.
case OptionExit:
Console.WriteLine("Exit");
break;
}
}
}

Solution: Use 'const' or 'if-else'

Option A: Change to const If the value is truly fixed and never changes, make it const.

public class Menu
{
// ✅ Correct: 'const' is known at compile-time.
public const int OptionExit = 9;

public void SelectOption(int input)
{
switch (input)
{
case OptionExit:
Console.WriteLine("Exit");
break;
}
}
}

Option B: Use if-else If the value must be dynamic (e.g., loaded from a config file), you cannot use a standard switch. Use if-else.

if (input == OptionExit) { /* ... */ }
note

Pattern Matching: Modern C# (7.0+) allows switch to use pattern matching (e.g., case int n when n == OptionExit:). This bypasses the constant requirement but changes the syntax slightly.

Scenario 2: Default Parameter Values

Optional arguments in methods (e.g., void DoWork(int retries = 3)) require the default value to be a compile-time constant. The compiler embeds this default value into the calling code.

Example of error

public class Config
{
public static int DefaultRetries = 3;

// ⛔️ Error CS0150: A constant value is expected
// You cannot use a variable as a default value.
public void Connect(int retries = DefaultRetries)
{
// ...
}
}

Solution: Use 'const' or Overloading

Option A: Use const

public class Config
{
// ✅ Correct: Made constant
public const int DefaultRetries = 3;

public void Connect(int retries = DefaultRetries)
{
// ...
}
}

Option B: Method Overloading If the default value cannot be constant (e.g., DateTime.Now), use method overloading.

public class Config
{
public void Connect()
{
// Pass the runtime value here
Connect(DateTime.Now.Second);
}

public void Connect(int seed)
{
// Actual logic
}
}

Scenario 3: Attribute Arguments

Attributes (metadata like [Obsolete], [Route], [DllImport]) are baked into the assembly metadata. Therefore, arguments passed to attributes must be constants.

Example of error

public class ApiController
{
public static string BasePath = "api/v1";

// ⛔️ Error CS0150: Attribute arguments must be constant.
[Route(BasePath)]
public void GetData() { }
}

Solution: Use 'const'

The value passed to the attribute must be a literal string or a const string.

public class ApiController
{
// ✅ Correct
public const string BasePath = "api/v1";

[Route(BasePath)]
public void GetData() { }
}

Conclusion

CS0150 is the compiler telling you that "I need to know this value right now, but you are giving me a value that won't exist until the program runs."

  1. Check the definition: Is the variable static readonly or just static? Change it to const if possible.
  2. Check the context: Are you inside a switch case, a parameter list (int x = ...), or an attribute [...]? These strictly require constants.
  3. Refactor: If the value must be dynamic, switch from switch to if-else, or use method overloading instead of default parameters.