Skip to main content

How to Resolve Error "CS0457: Ambiguous user defined conversions when converting from 'type1' to 'type2'" in C#

The Compiler Error CS0457 is an Ambiguity Error involving User-Defined Conversions. The message reads: "Ambiguous user defined conversions 'Conversion1' and 'Conversion2' when converting from 'TypeA' to 'TypeB'".

In C#, you can define custom implicit or explicit conversion operators (e.g., converting a custom Fahrenheit object automatically to a Celsius object). This error occurs when the compiler finds two or more valid paths to perform the requested conversion, and neither path is considered "better" or more specific than the other. The compiler refuses to guess which logic you intended to run.

This guide explains how these conflicts arise and how to eliminate the ambiguity.

Understanding Conversion Paths

C# allows you to define a conversion operator in either the Source type or the Destination type.

  • Converting A to B:
    • Class A can define public static implicit operator B(A a).
    • Class B can define public static implicit operator B(A a).

If both classes define this operator, the compiler sees two valid methods with the exact same signature. It doesn't know which class's logic to execute.

Scenario 1: Defining the Operator in Both Classes

This is a common design error. Two developers working on separate classes (TypeA and TypeB) both decide to implement the conversion logic between them.

Example of error:

public class A
{
// Logic defined in Source
public static implicit operator B(A a) => new B();
}

public class B
{
// Logic defined in Destination
public static implicit operator B(A a) => new B();
}

public class Program
{
static void Main()
{
A a = new A();

// ⛔️ Error CS0457: Ambiguous user defined conversions
// 'A.implicit operator B(A)' and 'B.implicit operator B(A)'
// when converting from 'A' to 'B'.
B b = a;
}
}

Scenario 2: Ambiguous Intermediate Conversions

The error can also occur if the conversion happens via an intermediate type, and multiple intermediate paths exist.

Imagine:

  • A converts to X. X converts to B.
  • A converts to Y. Y converts to B.

If you try to convert A to B, the compiler doesn't know if it should go via X or via Y.

Example of error:

public class A 
{
public static implicit operator int(A a) => 0;
public static implicit operator double(A a) => 0.0;
}

public class B
{
// B can be built from int OR double
public static implicit operator B(int i) => new B();
public static implicit operator B(double d) => new B();
}

public class Program
{
static void Main()
{
A a = new A();

// ⛔️ Error CS0457: Ambiguous conversion.
// Path 1: A -> int -> B
// Path 2: A -> double -> B
B b = a;
}
}

Solution 1: Remove the Duplicate Operator

For Scenario 1, the fix is architectural. A conversion relationship should be defined in only one place. Standard C# convention prefers defining the conversion in the class that "owns" the data or is the more specific of the two.

Solution: remove the operator from one of the classes.

public class A
{
// Kept this one
public static implicit operator B(A a) => new B();
}

public class B
{
// ✅ Correct: Removed the duplicate operator from Class B.
}

public class Program
{
static void Main()
{
A a = new A();
// Now there is only one path.
B b = a;
}
}

Solution 2: Use Explicit Casting to Direct the Path

For Scenario 2 (intermediate types), you can resolve the ambiguity by explicitly casting to the intermediate type first. This forces the compiler to choose a specific path.

Solution: cast A to int (or double) before assigning it to B.

public class Program
{
static void Main()
{
A a = new A();

// ✅ Correct: We explicitly chose the 'int' path.
// 1. A -> int
// 2. int -> B
B b = (int)a;
}
}

Conclusion

CS0457 means you have provided too many options for the compiler.

  1. Check Redundancy: Did you define operator B(A) in both class A and class B? Delete one.
  2. Check Intermediaries: Are there multiple ways to get from A to B (e.g., via float vs double)? Use an explicit cast to pick the route.