How to Resolve Error "CS0563: One of the parameters of a binary operator must be the containing type" in C#
The Compiler Error CS0563 is a signature restriction error regarding Operator Overloading. The message reads: "One of the parameters of a binary operator must be the containing type".
In C#, a Binary Operator works with two operands (e.g., x + y, x * y, x == y). When you define an operator overload inside a class or struct, C# requires that the operator logic be relevant to that specific class. You cannot use a custom class to redefine how two external types interact. For example, you cannot define operator +(int a, int b) inside a class named MyMath. That would attempt to redefine integer addition globally, which is forbidden.
This guide explains the valid signatures for binary operators.
Understanding Binary Operator Rules
When you overload a binary operator inside a class MyClass, the method signature looks like this:
public static ResultType operator +(Param1 p1, Param2 p2)
To ensure the operator belongs to MyClass, at least one of the parameters (p1 or p2) must be of type MyClass.
- Valid:
operator +(MyClass a, int b) - Valid:
operator +(int a, MyClass b) - Valid:
operator +(MyClass a, MyClass b) - Invalid:
operator +(int a, int b)(Defined insideMyClass)
Scenario: Attempting to Redefine External Types
This error often occurs when developers create a "Utility" class and try to add operator logic for built-in types (like int, string, or double) inside that class.
Example of error: attempting to define how two integers are added inside a generic MathUtils class.
public class MathUtils
{
// ⛔️ Error CS0563: One of the parameters of a binary operator must be the containing type.
// The containing type is 'MathUtils'.
// The parameters are 'int' and 'int'.
// Neither parameter is 'MathUtils', so this is illegal.
public static int operator +(int a, int b)
{
return a + b + 1; // Trying to change math logic
}
}
Solution: Include the Containing Type
To fix this, the operator must act on the class instance itself. If you want to add an integer to your custom object, one parameter must be your object.
Solution: modify the signature so that at least one parameter matches the class name.
public class SmartNumber
{
public int Value { get; set; }
public SmartNumber(int v) => Value = v;
// ✅ Correct: One parameter is 'SmartNumber'.
// This defines: SmartNumber + int
public static SmartNumber operator +(SmartNumber sn, int i)
{
return new SmartNumber(sn.Value + i);
}
// ✅ Correct: One parameter is 'SmartNumber'.
// This defines: int + SmartNumber (Commutative support)
public static SmartNumber operator +(int i, SmartNumber sn)
{
return new SmartNumber(i + sn.Value);
}
}
public class Program
{
static void Main()
{
var num = new SmartNumber(10);
var result = num + 5; // Valid
}
}
Extension Methods:
If your goal was purely to add functionality to built-in types (like int) without using your custom class, you cannot use operator overloading. Instead, use Extension Methods.
- You cannot write
3 + 5. - But you can write
3.CustomAdd(5).
Conclusion
CS0563 prevents "spooky action at a distance" where one class changes the behavior of unrelated types.
- Identify the Class: What class is the operator defined in?
- Identify the Parameters: Look at the two arguments
(A a, B b). - Check for Match: Does
AorBmatch the Class name? If not, the operator is invalid.