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) { /* ... */ }
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."
- Check the definition: Is the variable
static readonlyor juststatic? Change it toconstif possible. - Check the context: Are you inside a
switch case, a parameter list(int x = ...), or an attribute[...]? These strictly require constants. - Refactor: If the value must be dynamic, switch from
switchtoif-else, or use method overloading instead of default parameters.