How to Resolve Error "CS0557: Duplicate user-defined conversion in type" in C#
The Compiler Error CS0557 is a redundancy error regarding Operator Overloading. The message reads: "Duplicate user-defined conversion in type 'MyType'".
In C#, you can define custom conversion routines to convert your class to other types. However, you are only allowed to define one conversion path between any two specific types. You cannot define both an implicit operator AND an explicit operator for the same conversion (e.g., converting MyType to int). The compiler considers these to be the same signature for the purpose of conversion logic, and having both creates ambiguity.
This guide explains why this restriction exists and how to choose the correct conversion type.
Understanding Conversion Signatures
When you define a conversion operator:
public static implicit operator int(MyType x)public static explicit operator int(MyType x)
The compiler views both of these as a function roughly equivalent to: int Convert(MyType x).
If both exist, and you write int i = (int)myObj;, the compiler doesn't know which method to run. Even though one is marked "implicit" and the other "explicit", C# treats the Explicit cast syntax as capable of triggering Implicit operators as well. Therefore, defining both creates a conflict.
Scenario: Defining Both Implicit and Explicit
This error commonly occurs when a developer wants to support both styles of coding (automatic assignment and manual casting) and mistakenly thinks they need two separate methods.
Example of error:
public class Temperature
{
public double Degrees;
// 1. Implicit conversion (allows: double d = temp;)
public static implicit operator double(Temperature t)
{
return t.Degrees;
}
// 2. Explicit conversion (allows: double d = (double)temp;)
// ⛔️ Error CS0557: Duplicate user-defined conversion in type 'Temperature'
public static explicit operator double(Temperature t)
{
return t.Degrees;
}
}
Solution: Choose One Strategy
You must decide whether the conversion is Safe (always succeeds, no data loss) or Risky (potential data loss, exception throwing).
Option A: Use implicit (Safe)
If the conversion is safe (no precision loss, never throws exceptions), define it as implicit.
- This automatically enables explicit casting syntax as well.
double d = temp;(Works)double d = (double)temp;(Also works)
public class Temperature
{
public double Degrees;
// ✅ Correct: Defining implicit covers all bases.
public static implicit operator double(Temperature t)
{
return t.Degrees;
}
}
Option B: Use explicit (Risky)
If the conversion implies data loss (e.g., converting a high-precision Temperature to an int) or logical changes, use explicit.
- This forces the user to write the cast.
int i = temp;(Compiler Error - Prevents accidents)int i = (int)temp;(Works)
public class Temperature
{
public double Degrees;
// ✅ Correct: Casting to int loses decimals, so it must be explicit.
public static explicit operator int(Temperature t)
{
return (int)t.Degrees;
}
}
Conclusion
CS0557 prevents ambiguity in type conversion.
- Review Operators: Check your class for
operator TypeName. - Check for Duplicates: Do you have
implicit operator Xandexplicit operator X? - Pick One:
- Implicit includes Explicit behavior. Use this for lossless conversions.
- Explicit restricts usage to casts only. Use this for lossy conversions.