diff --git a/docs/csharp/language-reference/compiler-messages/cs0173.md b/docs/csharp/language-reference/compiler-messages/cs0173.md index cd694834869a3..ad6ee950046d5 100644 --- a/docs/csharp/language-reference/compiler-messages/cs0173.md +++ b/docs/csharp/language-reference/compiler-messages/cs0173.md @@ -1,7 +1,7 @@ --- description: "Compiler Error CS0173" title: "Compiler Error CS0173" -ms.date: 08/14/2018 +ms.date: 08/07/2025 f1_keywords: - "CS0173" helpviewer_keywords: @@ -10,28 +10,71 @@ ms.assetid: eb1797ad-bf62-4e2b-8922-bef4aff36954 --- # Compiler Error CS0173 -Type of conditional expression cannot be determined because there is no implicit conversion between 'class1' and 'class2' +Type of conditional expression cannot be determined because there is no implicit conversion between 'type1' and 'type2'. -Conversions between classes are useful when you want objects of different classes to work with the same code. However, two classes that work together cannot have mutual and redundant conversions, or no implicit conversions. The types of `class1` and `class2` are determined independently, and the more general type is selected as the type of the conditional expression. For more information about how types are determined, see [Conditional operator cannot cast implicitly](https://stackoverflow.com/questions/2215745/conditional-operator-cannot-cast-implicitly/2215959#2215959). +This error occurs when the compiler can't determine the type of a conditional expression because the two possible return values have no implicit conversion between them. This can happen with classes, value types, or any other types where there's no common type that both can be implicitly converted to. -To resolve CS0173, verify that there is one and only one implicit conversion between `class1` and `class2`, regardless of which direction the conversion is in and regardless of which class the conversion is in. For more information, see [User-defined conversion operators](../operators/user-defined-conversion-operators.md) and [Built-in numeric conversions](../builtin-types/numeric-conversions.md). +Starting with C# 9, *target-typed conditional expressions* allow the compiler to use the target type (the type being assigned to) to resolve ambiguity in some cases. However, CS0173 still occurs when using `var` or when there's no target type to guide the compiler. -## Example +To resolve CS0173, you can: -The following examples generate compiler error CS0173: +- Provide an explicit target type (available in C# 9+): + + ```csharp + object result = condition ? value1 : value2; // Works in C# 9.0+ + ``` + +- Use explicit casting: + + ```csharp + var result = condition ? (object)value1 : (object)value2; + ``` + +- Ensure there's an implicit conversion between the types by adding conversion operators or using compatible types. + +For more information, see [User-defined conversion operators](../operators/user-defined-conversion-operators.md) and [Built-in numeric conversions](../builtin-types/numeric-conversions.md). + +## Examples + +### Example 1: CS0173 with `var` (all C# versions) + +The following example generates CS0173 because `var` provides no target type for the compiler to use: + +```csharp +class Program +{ + static void Main() + { + // CS0173: Type of conditional expression can't be determined + // because there is no implicit conversion between 'int' and 'string'. + var result = true ? 100 : "ABC"; + } +} +``` + +To fix this, provide an explicit type: + +```csharp +// Fix: Use explicit target type (C# 9.0+). +object result = true ? 100 : "ABC"; // OK in C# 9.0+ + +// Or use explicit casting (all versions). +var result = true ? (object)100 : (object)"ABC"; +``` + +### Example 2: Class conversion example + +The following example shows CS0173 with custom classes: ```csharp public class C {} public class A { - // The following code defines an implicit conversion operator from - // type C to type A. + // Uncomment to add implicit conversion from C to A. //public static implicit operator A(C c) //{ - // A a = new A(); - // a = c; - // return a; + // return new A(); //} } @@ -42,33 +85,35 @@ public class MyClass A a = new A(); C c = new C(); - // The following line causes CS0173 because there is no implicit - // conversion from a to c or from c to a. - object o = b ? a : c; + // CS0173: No implicit conversion between A and C. + var result = b ? a : c; - // To resolve the error, you can cast a and c. - // object o = b ? (object)a : (object)c; + // Fix: Cast to common base type. + object result2 = b ? (object)a : (object)c; - // Alternatively, you can add a conversion operator from class C to - // class A, or from class A to class C, but not both. + // Or in C# 9.0+, provide target type. + object result3 = b ? a : c; // OK in C# 9.0+. } - - public static void Main() - { - F(true); - } } ``` +### Example 3: Version differences with nullable types + +The behavior of conditional expressions has evolved across C# versions: + ```csharp -class M +class Program { - static int Main () + static void Main() { - int X = 1; - // The following line causes CS0173. - object o = (X == 0) ? null : null; - return -1; + // This example shows how different C# versions handle the same code. + + // In C# 8.0 and earlier: CS8957 (feature not available). + // In C# 9.0+: Compiles successfully. + object? result = (1 == 0) ? null : null; } } ``` + +> [!NOTE] +> Starting with C# 9, target-typed conditional expressions allow the compiler to use the assignment target's type to resolve type ambiguity. In earlier versions, you might see error CS8957 instead of CS0173 when using language features not available in the current language version.