Overloading arithmetic, equality, and comparison operators in C#
Apr 1, 2023(rev. Sep 16, 2025) · 7 min
Table of Contents
This is post 2 in a 3-part series building up to a new C# 11 feature called Generic Math. Before tackling that though, I covered static abstract members (also new to C# 11), and now I want to look at overload operators (not new, but worth knowing).
In C# you can overload operators, putting you in control of how two instances of an object are related to one another. We’ll look at the different ways you can do that, but first…
The code in this post is available on GitHub, for you to use, expand upon, or just follow along while you read… and hopefully discover something new!
By overloading the arithmetic operators, you get to decide what it means to add two objects together. In Microsoft’s own example, they create a Fraction struct that defines what should happen when two fractions are added together, subtracted, etc.
Let’s define a Box class instead. We can decide to say that, if two boxes are added together, you should get back a box that could fit both of them. It’ll take the larger width and depth of the two boxes, and then combine their heights, so you can stack both smaller boxes inside the larger one. Notice how the overloaded operator is a static method that takes the two instance you want to compare (add, in this case).
This is incredibly not optimal, but judging by some of the packages I’ve gotten from Amazon with very small items inside, I might not be that far off from the industry standard. 😅
publicclassBox{publicBox(intwidth,intheight,intdepth){Width=width;Height=height;Depth=depth;}publicintWidth{get;privateset;}publicintHeight{get;privateset;}publicintDepth{get;privateset;}publicstaticBoxoperator+(Boxbox1,Boxbox2){varwidestWidth=Math.Max(box1.Width,box2.Width);vardeepestDepth=Math.Max(box1.Depth,box2.Depth);varcombinedHeight=box1.Height+box2.Height;returnnewBox(widestWidth,combinedHeight,deepestDepth);}}[Test]publicvoidAddingTwoBoxes_ReturnsBoxToFitBoth(){varbox1=newBox(2,3,7);varbox2=newBox(4,6,5);varbox3=box1+box2;Assert.Multiple(()=>{Assert.That(box3.Width,Is.EqualTo(4));// larger width from box2Assert.That(box3.Depth,Is.EqualTo(7));// larger depth from box1Assert.That(box3.Height,Is.EqualTo(9));// combined height});}
How about another? A Folder class this time, that can hold a list of files.. If someone tries to add two Folders together, they get back a new Folder with all the files in it, like this.
Both of the above examples overloaded the + operator, but there’s no reason you can’t overload a different operator.. or all of them. We’ll do one more with arithmetic, this time overloading the * operator.
How about a class that can hold shades of colors, kind of like a paint swatch? Multiplying two of them together should combine all the colors from one swatch with colors from the other, so 3 colors on one side and 3 on the other produces 9 “mixed” colors.
publicclassColorSwatch{publicIEnumerable<Color>Shades{get;}publicstringName{get;privateset;}publicColorSwatch(stringname,IEnumerable<Color>shades){Name=name;Shades=shades.ToList();}publicstaticIList<Color>operator*(ColorSwatchcs1,ColorSwatchcs2){varcolorMatrix=newList<Color>();varamount=0.5;foreach(vars1incs1.Shades){foreach(vars2incs2.Shades){// Thank you Timwi.. stackoverflow.com/a/3722337byter=(byte)(s1.R*amount+s2.R*(1-amount));byteg=(byte)(s1.G*amount+s2.G*(1-amount));byteb=(byte)(s1.B*amount+s2.B*(1-amount));colorMatrix.Add(Color.FromArgb(r,g,b));}}returncolorMatrix;}}
This one’s a little tougher to imagine the result of, so I wrote a quick little app that creates a colored square for each of the shades, and then a square for each “mixed” color. I won’t throw the code for that here, but it’s on GitHub too if you want to see it.
There’s comparison operators too, like greater than and less than. Using the Box class again, let’s decide that a box is less than another box if it’s area is smaller; likewise, it’s greater than another box if it’s area is larger.
This could be represented like this, where the operators are again static method that take two “box” objects to compare.
Let’s check out equality operators too, and then call it a day. :)
By overriding the == and != operators, you can decide what makes two instances equal. Building off of Microsoft’s example with the Fraction struct, you might do something like this. Of course this isn’t very robust since 1/2 and 2/4 won’t be seen as equal, but you get the idea.
Or maybe in that same Box class again, you want to be able to compare two boxes to see if they’re the same size. We could compare the area again like above, or maybe a different approach is to just check all 3 dimensions to see if they’re the same size, like this. Not very robust, but it’ll do for our purpose!
If you found this content useful, and want to learn more about a variety of C# features, check out this GitHub repo, where you’ll find links to plenty more blog posts and practical examples!