Operator Overloading Usage Guidelines
The following rules outline the guidelines for operator overloading:
Define operators on value types that are logical built-in language types, such as the System.Decimal Structure.
Provide operator-overloading methods only in the class in which the methods are defined. The C# compiler enforces this guideline.
Use the names and signature conventions described in the Common Language Specification (CLS). The C# compiler does this for you automatically.
Use operator overloading in cases where it is immediately obvious what the result of the operation will be. For example, it makes sense to be able to subtract one Time value from another Time value and get a TimeSpan. However, it is not appropriate to use the or operator to create the union of two database queries, or to use shift to write to a stream.
Overload operators in a symmetric manner. For example, if you overload the equality operator (==), you should also overload the not equal operator(!=).
Provide alternate signatures. Most languages do not support operator overloading. For this reason, it is a CLS requirement for all types that overload operators to include a secondary method with an appropriate domain-specific name that provides the equivalent functionality. It is a Common Language Specification (CLS) requirement to provide this secondary method. The following example is CLS-compliant.
public struct DateTime { public static TimeSpan operator -(DateTime t1, DateTime t2) { } public static TimeSpan Subtract(DateTime t1, DateTime t2) { } }
The following table contains a list of operator symbols and the corresponding alternative methods and operator names.
C++ operator symbol | Name of alternative method | Name of operator |
---|---|---|
Not defined | ToXxx or FromXxx | op_Implicit |
Not defined | ToXxx or FromXxx | op_Explicit |
+ (binary) | Add | op_Addition |
- (binary) | Subtract | op_Subtraction |
* (binary) | Multiply | op_Multiply |
/ | Divide | op_Division |
% | Mod | op_Modulus |
^ | Xor | op_ExclusiveOr |
& (binary) | BitwiseAnd | op_BitwiseAnd |
| | BitwiseOr | op_BitwiseOr |
&& | And | op_LogicalAnd |
|| | Or | op_LogicalOr |
= | Assign | op_Assign |
<< | LeftShift | op_LeftShift |
>> | RightShift | op_RightShift |
Not defined | LeftShift | op_SignedRightShift |
Not defined | RightShift | op_UnsignedRightShift |
== | Equals | op_Equality |
> | Compare | op_GreaterThan |
< | Compare | op_LessThan |
!= | Compare | op_Inequality |
>= | Compare | op_GreaterThanOrEqual |
<= | Compare | op_LessThanOrEqual |
*= | Multiply | op_MultiplicationAssignment |
-= | Subtract | op_SubtractionAssignment |
^= | Xor | op_ExclusiveOrAssignment |
<<= | LeftShift | op_LeftShiftAssignment |
%= | Mod | op_ModulusAssignment |
+= | Add | op_AdditionAssignment |
&= | BitwiseAnd | op_BitwiseAndAssignment |
|= | BitwiseOr | op_BitwiseOrAssignment |
, | None assigned | op_Comma |
/= | Divide | op_DivisionAssignment |
-- | Decrement | op_Decrement |
++ | Increment | op_Increment |
- (unary) | Negate | op_UnaryNegation |
+ (unary) | Plus | op_UnaryPlus |
~ | OnesComplement | op_OnesComplement |