Skip to main content

How to Resolve Error "CS0558: User-defined operator must be declared static and public" in C#

The Compiler Error CS0558 is a modifier restriction error regarding Operator Overloading. The message reads: "User-defined operator 'operator' must be declared static and public".

In C#, operators (such as +, -, ==, implicit, explicit) are considered utility logic belonging to the Type itself, not to a specific instance of that type. Furthermore, because operators are intended to be used anywhere the type is accessible (e.g., var sum = a + b;), they must be globally visible. Therefore, C# enforces that every operator overload must be marked with both public and static.

This guide explains the mandatory signature for operator overloads.

Understanding Operator Signatures​

Unlike methods, which can be private, virtual, or instance-based, operators have a strict contract. When the compiler encounters an expression like obj1 + obj2, it looks for a static method defined on the class of obj1 or obj2.

  • static: The operator does not have access to this. It works purely on the operands passed as parameters.
  • public: The operator must be usable by anyone who has access to the class. private or protected operators are not allowed because syntax like a + b doesn't support visibility checks well.

Scenario 1: Missing the static Modifier​

This is a common mistake when developers think of operators as methods acting on this object (like this.Add(other)). However, operators must define all inputs as parameters.

Example of error​

public class Vector
{
public int X { get; set; }
public int Y { get; set; }

// ⛔️ Error CS0558: User-defined operator must be declared static and public.
// Operators cannot be instance methods.
public Vector operator +(Vector a, Vector b)
{
return new Vector { X = a.X + b.X, Y = a.Y + b.Y };
}
}

Solution: Add static​

Add the static keyword to the signature.

public class Vector
{
public int X { get; set; }
public int Y { get; set; }

// ✅ Correct: The operator is now associated with the class type.
public static Vector operator +(Vector a, Vector b)
{
return new Vector { X = a.X + b.X, Y = a.Y + b.Y };
}
}

Scenario 2: Missing the public Modifier​

If you omit the access modifier, class members default to private. Even if you include static, forgetting public (or trying to use protected) will trigger this error.

Example of error​

public class Money
{
public decimal Amount { get; set; }

// ⛔️ Error CS0558: User-defined operator must be declared static and public.
// Missing 'public' means this defaults to 'private'.
static Money operator -(Money a, Money b)
{
return new Money { Amount = a.Amount - b.Amount };
}
}

Solution: Add public​

Make the operator explicitly public.

public class Money
{
public decimal Amount { get; set; }

// ✅ Correct: Explicitly marked as public.
public static Money operator -(Money a, Money b)
{
return new Money { Amount = a.Amount - b.Amount };
}
}
note

This rule applies to Implicit and Explicit conversion operators as well. public static implicit operator int(MyClass c) is required.

Conclusion​

CS0558 ensures that custom operators follow the language's design rules.

  1. Check Modifiers: Look at your operator definition.
  2. Ensure Both Exist: You must see public static before the operator keyword.
  3. No Exceptions: There are no private, protected, or internal operators in C#.