What is operator overloading in C#, and when is it appropriate?
Quick Answer
C# lets a type define what an operator means for it, via public static T operator +(T a, T b). It's appropriate for types that genuinely behave like values with well-known arithmetic/comparison semantics — Money, a Vector, a DateRange — where a + b reads naturally. Overriding ==/!= should be paired with overriding Equals/GetHashCode consistently.
Operator overloading lets you define what +, ==, and the rest mean for your own type, using a public static method named operator. It earns its keep on genuine value types where the operator has an obvious, unsurprising meaning — Money + Money, comparing two DateRanges for overlap. It's a bad idea when it would surprise a reader, like overloading + on something that isn't conceptually additive just because it's convenient. If I overload == I always overload != alongside it and make sure Equals and GetHashCode agree with it. These days, for a lot of these value-object cases, a record just generates the equality operators for me.
- Good fits: math/geometry types, money, ranges, custom numeric-like value objects.
- Bad fits: overloading
+on aLoggerto mean “attach a handler” — surprising to a reader, avoid cute abuse. - If you overload
==, also overload!=, and implementIEquatable<T>for performance in generic collections. recordtypes generate value-equality operators for you, often removing the need to hand-write them.