Skip to main content

How to Resolve Error "CS0567: Conversion, equality, or inequality operators declared in interfaces must be abstract or virtual" in C#

The Compiler Error CS0567 is a syntax error related to C# 11 (and later) features, specifically Static Abstract Members in Interfaces.

The message reads: "Conversion, equality, or inequality operators declared in interfaces must be abstract or virtual".

Prior to C# 11, interfaces could not contain operators at all. With the introduction of Generic Math, interfaces can now declare operators (like ==, !=, +, or implicit conversions). However, because an interface typically describes a contract rather than an implementation, these operators generally cannot be "sealed" or static-only within the interface itself. They must be marked as abstract (forcing the implementing class to define the logic) or virtual (allowing the implementing class to override the logic).

This guide explains how to correctly define operator contracts within interfaces.

Understanding Operators in Interfaces

In C#, operators (like operator +) are always static. When you declare a static member in an interface (a feature added in .NET 7 / C# 11), you have two choices:

  1. Implementation: You provide the code body { ... }.
  2. Contract: You want the class that implements the interface to provide the code.

For Equality (==, !=) and Conversion (implicit, explicit) operators, the logic depends entirely on the concrete data inside the class. Therefore, the interface cannot usually provide a default implementation. It must delegate this responsibility to the class. To do this, you must explicitly mark the operator as abstract (or virtual).

Scenario: Declaring an Operator without Modifiers

This error occurs when you try to define an operator signature in an interface but treat it like a standard method declaration or a standard static member, forgetting the polymorphism keywords.

Example of error:

public interface ICustomEquatable<T> where T : ICustomEquatable<T>
{
// ⛔️ Error CS0567: Conversion, equality, or inequality operators
// declared in interfaces must be abstract or virtual.
// The compiler needs to know: "Who implements this logic?"
static bool operator ==(T left, T right);

// ⛔️ Error CS0567
static bool operator !=(T left, T right);
}

Solution: Use the abstract Modifier

To fix this, you must add the abstract keyword. This tells the compiler: "I am defining a contract. Any class T that implements this interface MUST provide a static operator ==."

Solution:

public interface ICustomEquatable<T> where T : ICustomEquatable<T>
{
// ✅ Correct: 'static abstract' defines the contract.
static abstract bool operator ==(T left, T right);

// ✅ Correct: Remember to pair equality operators.
static abstract bool operator !=(T left, T right);
}
note

Why abstract and not just static? A normal static member in an interface belongs to the interface itself (e.g., ICustomEquatable.SomeHelper()). A static abstract member belongs to the implementing type (e.g., MyClass.operator==). Operators need to belong to the implementing type to be useful.

Implementing the Interface

Once you have defined the interface correctly (Solution above), the error CS0567 is resolved. However, you must now correctly implement that interface in your class.

Example of implementation:

public class IDCard : ICustomEquatable<IDCard>
{
public int IdNumber { get; set; }

// Implementation of the interface contract
public static bool operator ==(IDCard left, IDCard right)
{
if (left is null) return right is null;
return left.IdNumber == right?.IdNumber;
}

public static bool operator !=(IDCard left, IDCard right)
{
return !(left == right);
}

// Standard overrides required when overloading ==
public override bool Equals(object obj) => false; // Simplified for example
public override int GetHashCode() => IdNumber;
}

Conclusion

CS0567 is a syntax enforcement for the C# 11 "Static Abstract Members" feature.

  1. Check the Context: Are you inside an interface?
  2. Check the Member: Is it an operator (==, !=, implicit, explicit)?
  3. The Fix: You must add abstract (or virtual) to the signature. You cannot define these operators as simple static members without polymorphism.