Skip to main content

How to Resolve Error "CS0552: User-defined conversions to or from an interface are not allowed" in C#

The Compiler Error CS0552 is a design restriction error regarding Operator Overloading. The message reads: "User-defined conversions to or from an interface are not allowed".

In C#, you can define custom conversion logic (using implicit or explicit operators) to convert between classes or structs. However, you are forbidden from defining these operators if the source or destination type is an Interface.

This is because the C# runtime already handles interface conversions automatically via Reference Conversion (boxing/casting). Creating a custom operator would conflict with the built-in behavior of the language, creating ambiguity about whether you intend to cast the reference or transform the data.

Understanding Interface Conversions

C# has strict rules for interfaces:

  • Upcasting (Implicit): If ClassA implements InterfaceI, you can assign an instance of ClassA to a variable of type InterfaceI automatically. This is a built-in reference conversion.
  • Downcasting (Explicit): If you have a variable of type InterfaceI, you can cast it back to ClassA using (ClassA)myInterface. This checks the runtime type.

If you try to write a method public static implicit operator InterfaceI(ClassA a), you are trying to override or duplicate this built-in mechanics, which the compiler rejects to prevent unpredictable behavior.

Scenario: Attempting the Illegal Conversion

The most common mistake is thinking you need to manually "teach" the compiler how to turn your class into an interface.

Example of error:

public interface IDocument
{
void Print();
}

public class PdfFile
{
public string Content { get; set; }

// ⛔️ Error CS0552: User-defined conversions to or from an interface are not allowed.
// The compiler forbids defining a custom path to 'IDocument'.
public static implicit operator IDocument(PdfFile file)
{
return new Wrapper(file); // Hypothetical logic
}
}

Solution 1: Implement the Interface (Reference Conversion)

If your goal is to allow your class to be assigned to an interface variable, simply implement the interface on the class. The conversion becomes automatic.

Solution: add the interface to the class declaration.

public interface IDocument
{
void Print();
}

// ✅ Correct: Implement the interface directly.
public class PdfFile : IDocument
{
public string Content { get; set; }

public void Print()
{
System.Console.WriteLine("Printing PDF...");
}
}

public class Program
{
static void Main()
{
PdfFile myPdf = new PdfFile();

// ✅ Valid: Built-in implicit reference conversion
IDocument doc = myPdf;
}
}

Solution 2: Use Constructors or Factory Methods

Sometimes, you actually do want to transform data. For example, you have an IWidget (from a 3rd party library) and you want to convert it into your own MyWidget class. Since you cannot write implicit operator MyWidget(IWidget w), you must use a standard method or constructor.

Solution: use a constructor or a static creation method.

public interface IWidget 
{
int Id { get; }
}

public class MyWidget
{
public int Id { get; set; }

// ⛔️ Invalid: public static implicit operator MyWidget(IWidget w) { ... }

// ✅ Correct: Use a constructor for the conversion logic
public MyWidget(IWidget source)
{
this.Id = source.Id;
}

// ✅ Correct: Or use a static factory method
public static MyWidget FromWidget(IWidget source)
{
return new MyWidget(source);
}
}
note

This approach makes the conversion explicit and clear to the reader (e.g., var w = new MyWidget(interfaceObj);), avoiding the confusion of implicit magic.

Conclusion

CS0552 enforces the rule that interfaces are about Identity and Contracts, not data transformation.

  1. If the class is the interface: Implement the interface in the class definition. C# handles the conversion for you.
  2. If the class wraps the interface: Use a Constructor or Factory Method to create the new object.
  3. Never define operator InterfaceName or operator ClassName(InterfaceName).