How to Resolve Error "CS0172: Type of conditional expression cannot be determined" in C#
The Compiler Error CS0172 is a Type Inference Ambiguity error related to the Ternary Conditional Operator (? :). The message reads: "Type of conditional expression cannot be determined because 'TypeA' and 'TypeB' implicitly convert to one another".
When you write condition ? A : B, the compiler must determine a single result type for the entire expression. It looks at A and B and asks:
- Can
Abe converted toB? - Can
Bbe converted toA?
Ideally, one direction works and the other doesn't (e.g., int converts to double, but double doesn't implicitly convert to int). If BOTH conversions are possible (implicitly), the compiler cannot decide which type you intended the result to be. It refuses to guess and throws CS0172.
This guide explains how circular conversions create this deadlock and how to resolve it.
Understanding Ternary Type Inference
The ternary operator (? :) does not just return "whatever object was picked." It must statically define a type at compile-time.
- Valid:
true ? 1 : 1.5->intconverts todouble. Result type isdouble. - Valid:
true ? "A" : null->nullconverts tostring. Result type isstring. - Invalid (CS0172):
true ? ObjA : ObjB-> IfObjAconverts toObjBANDObjBconverts toObjA, there is no clear "better" type.
Scenario: Circular Implicit Conversions
This error usually happens when working with custom classes where developers have been overly generous with implicit operator definitions.
Example of error: imagine two classes, Fahrenheit and Celsius, that can automatically convert to each other.
public class Fahrenheit
{
// Implicitly converts to Celsius
public static implicit operator Celsius(Fahrenheit f) => new Celsius();
}
public class Celsius
{
// Implicitly converts to Fahrenheit
public static implicit operator Fahrenheit(Celsius c) => new Fahrenheit();
}
public class Program
{
static void Main()
{
Fahrenheit f = new Fahrenheit();
Celsius c = new Celsius();
bool useFahrenheit = true;
// ⛔️ Error CS0172: Type of conditional expression cannot be determined
// because 'Fahrenheit' and 'Celsius' implicitly convert to one another.
// Compiler: "Should the result variable be Fahrenheit or Celsius? Both are valid."
var result = useFahrenheit ? f : c;
}
}
Solution: Explicit Casting
To fix the ambiguity, you must pick a winner. Cast one of the operands to the type of the other. This tells the compiler explicitly which type the final result must be.
Solution: if you want the result to be Celsius, cast the Fahrenheit object to Celsius.
public class Program
{
static void Main()
{
Fahrenheit f = new Fahrenheit();
Celsius c = new Celsius();
bool useFahrenheit = true;
// ✅ Correct: We force 'f' to become 'Celsius'.
// Now both sides are 'Celsius'. The result is 'Celsius'.
var result = useFahrenheit ? (Celsius)f : c;
// Verify the type
System.Console.WriteLine(result.GetType().Name); // Output: Celsius
}
}
Alternatively, if you want Fahrenheit:
// ✅ Correct: Both sides become 'Fahrenheit'.
var result = useFahrenheit ? f : (Fahrenheit)c;
Conclusion
CS0172 is the compiler asking you to break a tie.
- Identify the Types: Look at the two objects in your
? :statement. - Check Conversions: Do they both define implicit operators pointing to each other?
- Decide the Result: Choose which type you want the expression to return.
- Cast: Explicitly cast one side to match that chosen type.