How to Resolve Error "CS0564: The first operand of an overloaded shift operator must have the same type as the containing type" in C#
The Compiler Error CS0564 is a signature restriction error regarding Operator Overloading, specifically for the bitwise shift operators (<< and >>).
The error message reads: "The first operand of an overloaded shift operator must have the same type as the containing type".
In C#, most binary operators (like + or *) are flexible; they allow the containing class to appear as either the left or right operand. However, shift operators are stricter. When you define a shift operator inside a class or struct, the first parameter (the value being shifted) must be an instance of that class or struct.
This guide explains the specific signature requirements for shift operators and how to implement them correctly.
Understanding Shift Operator Syntax
The Left Shift (<<) and Right Shift (>>) operators generally follow this logic:
Result = Value << Amount
To overload this in C#, the method signature must strictly match this pattern:
public static ResultType operator << (ContainingType value, int shiftAmount)
- Operand 1 (Left): Must be the Containing Type (the class you are writing the code in).
- Operand 2 (Right): Must be
int(the number of bits to shift).
If Operand 1 is not the containing type, the compiler raises CS0564.
Scenario: Defining the Wrong First Operand
This error often occurs when a developer gets the parameter order confused, or tries to define an operator that shifts a primitive integer into a custom type (reverse shifting).
Example of error: in this example, we define the operator inside MyBitField, but we define the first parameter as int.
public class MyBitField
{
public int Value { get; set; }
// ⛔️ Error CS0564: The first operand of an overloaded shift operator
// must have the same type as the containing type.
// Here, the first operand is 'int', but the containing type is 'MyBitField'.
public static MyBitField operator <<(int shiftAmount, MyBitField field)
{
return new MyBitField { Value = field.Value << shiftAmount };
}
}
This syntax implies usage like 5 << myObject, which C# does not support for custom types in this specific manner.
Solution: Correcting the Signature
To fix this, ensure the first parameter matches the class definition.
Solution: swap the parameters so the custom class is first.
public class MyBitField
{
public int Value { get; set; }
// ✅ Correct: The first operand is 'MyBitField'.
// Usage: myObject << 5
public static MyBitField operator <<(MyBitField field, int shiftAmount)
{
return new MyBitField { Value = field.Value << shiftAmount };
}
}
public class Program
{
static void Main()
{
var bits = new MyBitField { Value = 1 };
// This now works
var result = bits << 2;
}
}
What about the second operand?
The second operand (the shift amount) must be an int. If you try to make the second operand a long or a custom type, you will receive a different error (CS0563: "One of the parameters of a binary operator must be the containing type").
Conclusion
CS0564 enforces the semantics of bitwise shifting.
- Check the Operator: Are you overloading
<<or>>? - Check the First Parameter: Is it the exact type of the class/struct you are currently in?
- The Fix: Ensure the signature is
operator <<(MyType a, int b). You cannot defineoperator <<(int a, MyType b).