Operator overloading or ad-hoc polymorphism lets you work with user defined types much the same way you work with fundamental data types Polymorphism is one of the basic principles of OOP (Object Oriented Programming). The word Polymorphism is derived from two words — “poly” meaning many, and “morph” meaning forms. Hence, polymorphism implies the existence of the same thing but in different forms. Operator overloading is an example of static polymorphism. You can leverage operator overloading or to add functionality to operators so as to work with user defined types much the same way you work with fundamental data types. What are the operators and what are the operators that can be overloaded? In an expression you typically have operators and operands. Operators are those that work on operands and they all are part of an expression. As an example, the following is an expression that contains two operands and one operator. The operands are X and Y and the operator is +. X + Y Operators are classified as unary, binary, comparison, assignment, etc. depending on their purpose and the number of operands on which the operators would work. Although most of the operators can be overloaded, certain restrictions apply. In essence, not all operators can be overloaded. The unary operators i.e., operators that work with one operand can be overloaded. You can also overload binary operators and comparison operators like, ==, !=, , =. However, you cannot overload the =, ?, ->, new, is, sizeof or typeof operators. You cannot also overload the conditional operators like && and || easily. Also, the array indexing operator [] cannot be overloaded. You can learn more on what all operators can be overloaded from this MSDN article. Implementing operator overloading in C# In this section we will explore how we can implement operator overloading in C#. Consider the following class named DistanceCalculator. public class DistanceCalculator { Int32 feet = 0, inch = 0; public DistanceCalculator(Int32 feet = 0, Int32 inch = 0) { this.feet = feet; this.inch = inch; } } Refer to the code listing above. The DistanceCalculator class contains two data members of type Int32, namely, feet and inch. We would now add more methods to this class to illustrate how operators can be overloaded. When working with operator overloading, you need to keep certain points in mind. The operator to be overloaded should have a corresponding method that is marked with the keyword operator. The arguments to the operator function are operands and your operator function can return a value. The operator function should be static and it should be a member of the containing type. The following code snippet illustrates how a typical operator function would look like. This example shows how the == and != operators can be overloaded. public static bool operator ==(DistanceCalculator obj1, DistanceCalculator obj2) { return obj1.Value == obj2.Value; } public static bool operator !=(DistanceCalculator obj1, DistanceCalculator obj2) { return obj1.Value != obj2.Value; } Note that Value is a property that returns the value in terms of inch. public Int32 Value { get { return (feet * 12) + inch; } } Here’s the complete code listing of the DistanceCalculator class. public class DistanceCalculator { Int32 feet = 0, inch = 0; public DistanceCalculator(Int32 feet = 0, Int32 inch = 0) { this.feet = feet; this.inch = inch; } public static bool operator ==(DistanceCalculator obj1, DistanceCalculator obj2) { return obj1.Value == obj2.Value; } public static bool operator !=(DistanceCalculator obj1, DistanceCalculator obj2) { return obj1.Value != obj2.Value; } public override bool Equals(object obj) { DistanceCalculator distanceCalculator = obj as DistanceCalculator; if (distanceCalculator != null) { return (distanceCalculator == this); } return false; } public override int GetHashCode() { return Value.GetHashCode(); } public Int32 Feet { get { return feet; } } public Int32 Inch { get { return inch; } } public Int32 Value { get { return (feet * 12) + inch; } } } The following code snippet illustrates how you can use the DistanceCalculator class. static void Main(string[] args) { DistanceCalculator obj1 = new DistanceCalculator(1, 2); DistanceCalculator obj2 = new DistanceCalculator(1, 2); Console.WriteLine((obj1 == obj2).ToString()); Console.Read(); } The following code snippet shows how you can overload the + operator to add two objects. public static DistanceCalculator operator +(DistanceCalculator obj1, DistanceCalculator obj2) { Int32 totalInches = obj1.Value + obj2.Value; Int32 feet = totalInches / 12; Int32 inch = totalInches % 12; DistanceCalculator temp = new DistanceCalculator(feet, inch); return temp; } Let’s add the following two properties to the DistanceCalculator class. The following code snippet shows how you can add two objects of type DistanceCalculator and return the resultant object as the same type, i.e., the returned object is of type DistanceCalculator. public Int32 Feet { get { return feet; } } public Int32 Inch { get { return inch; } } Here’s how you can create two instances of the DistanceCalculator class and take advantage of the overloaded operator function to assign the result in another object of the same type. static void Main(string[] args) { DistanceCalculator obj1 = new DistanceCalculator(1, 11); DistanceCalculator obj2 = new DistanceCalculator(1, 2); DistanceCalculator obj3 = obj1 + obj2; Console.WriteLine("Feet: "+obj3.Feet.ToString()); Console.WriteLine("Inch: " + obj3.Inch.ToString()); Console.Read(); } Related content how-to How to use FastEndpoints in ASP.NET Core Take advantage of the free open-source FastEndpoints library to build fast and lean APIs in your ASP.NET Core applications. By Joydip Kanjilal Jul 11, 2024 7 mins Microsoft .NET C# Development Libraries and Frameworks how-to How to use Refit to consume APIs in ASP.NET Core Take advantage of Refit REST library to simplify API consumption and make your code cleaner, more efficient, and easier to maintain. By Joydip Kanjilal Jul 04, 2024 10 mins C# Microsoft .NET Software Deployment how-to When to use an abstract class vs. interface in C# Understanding the differences between an abstract class and interface is key to designing loosely coupled and extensible applications. By Joydip Kanjilal Jun 20, 2024 10 mins Small and Medium Business Microsoft .NET C# how-to 6 security best practices for ASP.NET Core Learn the best practices and built-in safeguards for preventing attacks and protecting sensitive data in your ASP.NET Core web applications. By Joydip Kanjilal Jun 07, 2024 6 mins C# Microsoft .NET Web Development Resources Videos