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 tothis. It works purely on the operands passed as parameters.public: The operator must be usable by anyone who has access to the class.privateorprotectedoperators are not allowed because syntax likea + bdoesn'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 };
}
}
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.
- Check Modifiers: Look at your
operatordefinition. - Ensure Both Exist: You must see
public staticbefore theoperatorkeyword. - No Exceptions: There are no private, protected, or internal operators in C#.