How to Resolve Warning "CS0665: Assignment in conditional expression is always constant" in C#
The Compiler Warning CS0665 is a code logic warning. The message reads: "Assignment in conditional expression is always constant; did you mean to use == instead of = ?".
This warning identifies a very common typo: using the Assignment Operator (=) instead of the Equality Operator (==) inside an if or while statement. Because C# allows assignments to return a value, writing if (x = true) is syntactically valid code that assigns true to x and then enters the if block. However, since the result is always true (or always false), the conditional check is useless, and the logic is likely flawed.
This guide explains why this typo is dangerous and how to correct it.
Understanding Assignment vs. Comparison
=(Assignment): Sets the variable on the left to the value on the right. Returns the assigned value.==(Equality): Checks if the left side equals the right side. Returns a boolean result.
When you write if (isValid = true), the compiler sees this:
- Set
isValidtotrue. - The result of the operation is
true. - Check
if (true). - Execute the block.
This overwrites your variable and ignores its previous state entirely.
Scenario 1: The "Always True" Condition
This is the most frequent occurrence. You intend to check if a flag is set, but you accidentally force it to be set.
Example of Warning
public void ProcessOrder(bool isPaid)
{
// ⛔️ Warning CS0665: Assignment in conditional expression is always constant.
// This line DOES NOT check if isPaid is true.
// It MAKES isPaid true, and then runs the block.
if (isPaid = true)
{
Console.WriteLine("Order processed.");
}
}
Solution: Use Equality or Implicit Boolean
Change the operator to ==, or simply use the boolean variable directly (the most idiomatic C# style).
public void ProcessOrder(bool isPaid)
{
// ✅ Correct: Using the equality operator
if (isPaid == true)
{
Console.WriteLine("Order processed.");
}
// ✅ Correct (Best Practice): Implicit boolean check
if (isPaid)
{
Console.WriteLine("Order processed.");
}
}
Scenario 2: The "Dead Code" Loop
If you accidentally assign false inside a loop condition, the loop will never run.
Example of Warning
public void WaitForSignal()
{
bool running = true;
// ⛔️ Warning CS0665
// 1. Assigns 'false' to 'running'.
// 2. Evaluates 'while(false)'.
// 3. The loop body is unreachable (dead code).
while (running = false)
{
Console.WriteLine("Waiting...");
}
}
Solution: Correct Logic
public void WaitForSignal()
{
bool running = true;
// ✅ Correct: Loop continues as long as running is false (example logic)
while (running == false)
{
// ...
}
// ✅ Correct: Or logically negated
while (!running) { }
}
Valid Assignment Patterns (Double Parentheses)
Sometimes, you do want to assign a variable and check its value in the same line. This is common when reading streams or iterating through linked lists.
If the assignment is not constant (e.g., it comes from a method call, not a literal true/false), CS0665 usually doesn't trigger, but other code style analyzers might complain. To tell the compiler (and readers) "I really meant to do this assignment," wrap the assignment in double parentheses.
Example: Reading Logic
string line;
using (var reader = new StreamReader("data.txt"))
{
// This is valid C# and rarely triggers CS0665 because the result isn't constant.
// However, adding extra parentheses makes the intent explicit.
// ✅ Correct pattern: Assign, then check the result of the assignment
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
CS0665 specifically targets constant assignments (like = true or = false). If you are assigning a method result, you are usually safe from this specific warning, but explicit comparison (like != null) is safer than relying on implicit truthiness.
Conclusion
CS0665 is almost always a typo detection.
- Check Operators: Did you type
=(Set) instead of==(Check)? - Simplify Booleans: Instead of
if (x == true), just writeif (x). This prevents the typo entirely. - Verify Logic: Ensure you aren't overwriting your control flags inside the
ifstatement itself.