Operator Overloading
Part of the Object Oriented Programming section of Coddy's C# journey — lesson 36 of 70.
Operator overloading lets you define how operators like +, -, or == behave with your custom classes. Instead of calling methods like point1.Add(point2), you can write the more natural point1 + point2.
To overload an operator, you create a special static method using the operator keyword:
public class Vector
{
public int X { get; }
public int Y { get; }
public Vector(int x, int y)
{
X = x;
Y = y;
}
public static Vector operator +(Vector a, Vector b)
{
return new Vector(a.X + b.X, a.Y + b.Y);
}
}Now you can add vectors naturally:
Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2; // X = 4, Y = 6The method must be public static, and at least one parameter must be the containing type. You can overload arithmetic operators (+, -, *, /), comparison operators (==, !=, <, >), and unary operators (-, !, ++).
Note that comparison operators must be overloaded in pairs - if you define ==, you must also define !=.
Use operator overloading when it makes your code more intuitive, particularly for mathematical types like vectors, complex numbers, or money. Avoid it when the operation's meaning isn't immediately obvious.
Challenge
EasyLet's build a Fraction class that makes working with fractions feel natural through operator overloading. Instead of calling methods like fraction1.Add(fraction2), you'll be able to write the intuitive fraction1 + fraction2.
You'll organize your code across two files:
Fraction.cs: Create aFractionclass in theMathnamespace that represents a fraction with a numerator and denominator. Your fraction should have:- Two read-only integer properties:
NumeratorandDenominator - A constructor that accepts the numerator and denominator (in that order)
- An overloaded
+operator that adds two fractions using the formula:(a/b) + (c/d) = (a*d + c*b) / (b*d) - An overloaded
*operator that multiplies two fractions:(a/b) * (c/d) = (a*c) / (b*d) - An overloaded
==operator that returnstrueif two fractions are equal (cross-multiply to compare:a*d == c*b) - An overloaded
!=operator (required when you overload==) that returns the opposite of== - A method
GetDisplay()that returns the fraction as a string in the format"{Numerator}/{Denominator}"
- Two read-only integer properties:
Program.cs: In your main file, create two fractions using input values. Demonstrate the overloaded operators by adding them, multiplying them, and checking if they're equal. Print the results to show your operators working naturally.
You will receive four inputs:
- First fraction's numerator (integer)
- First fraction's denominator (integer)
- Second fraction's numerator (integer)
- Second fraction's denominator (integer)
Print the output in this format:
Fraction 1: {GetDisplay()}
Fraction 2: {GetDisplay()}
Sum: {GetDisplay()}
Product: {GetDisplay()}
Are equal: {True/False}For example, if the inputs are 1, 2, 2, and 4, the output should be:
Fraction 1: 1/2
Fraction 2: 2/4
Sum: 8/8
Product: 2/8
Are equal: TrueNotice how 1/2 and 2/4 are recognized as equal because 1*4 == 2*2. The sum and product are calculated without simplification - that's fine for this challenge. The beauty is in how naturally you can now work with fractions using familiar operators!
Cheat sheet
Operator overloading allows you to define custom behavior for operators like +, -, *, == with your classes.
To overload an operator, create a public static method using the operator keyword. At least one parameter must be the containing type:
public class Vector
{
public int X { get; }
public int Y { get; }
public Vector(int x, int y)
{
X = x;
Y = y;
}
public static Vector operator +(Vector a, Vector b)
{
return new Vector(a.X + b.X, a.Y + b.Y);
}
}Usage:
Vector v1 = new Vector(3, 4);
Vector v2 = new Vector(1, 2);
Vector v3 = v1 + v2; // X = 4, Y = 6You can overload:
- Arithmetic operators:
+,-,*,/ - Comparison operators:
==,!=, <code><,(must be overloaded in pairs) - Unary operators:
-,!,++
When overloading ==, you must also overload !=:
public static bool operator ==(Vector a, Vector b)
{
return a.X == b.X && a.Y == b.Y;
}
public static bool operator !=(Vector a, Vector b)
{
return !(a == b);
}Try it yourself
using System;
using Math;
class Program
{
public static void Main(string[] args)
{
// Read input for first fraction
int num1 = Convert.ToInt32(Console.ReadLine());
int den1 = Convert.ToInt32(Console.ReadLine());
// Read input for second fraction
int num2 = Convert.ToInt32(Console.ReadLine());
int den2 = Convert.ToInt32(Console.ReadLine());
// TODO: Create two Fraction objects using the input values
// TODO: Use the overloaded + operator to add the fractions
// TODO: Use the overloaded * operator to multiply the fractions
// TODO: Use the overloaded == operator to check equality
// TODO: Print the output in the required format:
// Fraction 1: {GetDisplay()}
// Fraction 2: {GetDisplay()}
// Sum: {GetDisplay()}
// Product: {GetDisplay()}
// Are equal: {True/False}
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesNamespaces & DirectivesIntro to Classes & ObjectsThe 'this' KeywordMethods and ParametersFields vs PropertiesConstructorsObject InitializersRecap - Simple Calculator4Inheritance
Basic Inheritance (:) SyntaxThe 'base' KeywordVirtual & Override KeywordsSealed ClassesThe 'object' Base ClassRecap - Employee Hierarchy7Advanced Features
Operator OverloadingIndexers (this[])ToString() OverrideExtension MethodsRecap - Custom List2Properties & Static Members
Auto-Implemented PropertiesRead/Write-Only PropertiesStatic Fields & MethodsStatic ClassesExpression-Bodied Members5Polymorphism & Interfaces
Compile vs Runtime PolyInterface vs Abstract ClassMultiple InterfacesExplicit InterfacesUpcasting & DowncastingRecap - Shape Calculator