This is the third entry in the series about operators in C#. This time, we'll see how to overload binary operators and some use cases for them.
Previous entries:
Binary operators
As you might know, binary operators are those that apply to two operands. Most of them are math operators and some others are logical operators, as well as equality/comparison operators.
The binary operators available for overload in C# are:
- Addition (+)
- Subtration (-)
- Product (*)
- Division (/)
- Logical AND (&) and logical OR (|)
- Logical XOR (^)
- Left shift (<<) and Right Shift (>>)
- Comparison operators
- Equality (==)
- Inequality (!=)
- Lesser than (<)
- Greater than (>)
- Lesser or equal than (<=)
- Greater or equal than (>=)
Addition
Continuing with the Temperature data class, we will override the binary addition operator so it can sum two temperatures that are in different scales.
To keep the code consise, I'll only consider converting from Celsius to Farenheit and viceversa:
public static Temperature operator +(Temperature tempA, Temperature tempB)
{
if (tempA.Type == tempB.Type) tempA.Value += tempB.Value;
if (tempA.Type == TemperatureType.Celsius && tempB.Type == TemperatureType.Farentheit)
{
double tempInCelsius = (tempB.Value - 32) * (5d / 9d);
tempA.Value += tempInCelsius;
}
else if (tempA.Type == TemperatureType.Farentheit && tempB.Type == TemperatureType.Celsius)
{
double tempInFarenheit = tempB.Value * (9d / 5d) + 32;
tempA.Value += tempInFarenheit;
}
return tempA;
}
An then you could use it like this:
var celsius = new Temperature(20, TemperatureType.Celsius);
var farenheit = new Temperature(68, TemperatureType.Farentheit);
celsius = celsius + farenheit;
// Prints "The current temperature in Celsius is: 40"
Console.WriteLine("The current temperature in Celsius is: " + celsius.Value);
Console.ReadLine();
Subtraction
The code for the subtraction operator is almost the same as for the addition:
public static Temperature operator +(Temperature tempA, Temperature tempB)
{
if (tempA.Type == tempB.Type) tempA.Value -= tempB.Value;
if (tempA.Type == TemperatureType.Celsius && tempB.Type == TemperatureType.Farentheit)
{
double tempInCelsius = (tempB.Value - 32) * (5d / 9d);
tempA.Value -= tempInCelsius;
}
else if (tempA.Type == TemperatureType.Farentheit && tempB.Type == TemperatureType.Celsius)
{
double tempInFarenheit = tempB.Value * (9d / 5d) + 32;
tempA.Value -= tempInFarenheit;
}
return tempA;
}
and so on for the product and division operators.
Logical operators
You can override the logical AND and OR operators in order to modify the behavior of the && and || operators for use in condition statements. We'll briefly see their definition along the XOR operator and a simple example of using them.
For the AND operator we'll return true if their types are the same.
For the OR operator we'll return true if either value is above a threshold.
And for the XOR operator we'll return true if their types are different.
public static bool operator &(Temperature tempA, Temperature tempB)
{
if (tempA.Type == tempB.Type) return true;
else return false;
}
public static bool operator |(Temperature tempA, Temperature tempB)
{
var tempAInCelsius = tempA.Type == TemperatureType.Celsius ? tempA.Value : (tempA.Value - 32) * (5d / 9d);
var tempBInCelsius = tempB.Type == TemperatureType.Celsius ? tempB.Value : (tempB.Value - 32) * (5d / 9d);
if (tempAInCelsius >= 37 || tempBInCelsius >= 37) return false;
else return true;
}
public static bool operator ^(Temperature tempA, Temperature tempB)
{
if (tempA.Type != tempB.Type) return true;
else return false;
}
With that, then we can use the overloaded operators as follows
var celsius = new Temperature(20, TemperatureType.Celsius);
var farenheit = new Temperature(68, TemperatureType.Farentheit);
if (celsius & farenheit)
{
Console.WriteLine("The temperatures are equivalent");
}
if (celsius | farenheit)
{
Console.WriteLine("The temperatures are cool");
}
if (celsius ^ farenheit)
{
Console.WriteLine("The temperatures are different");
}
//Prints "The temperature are coool" and "The temperatures are different"
Console.ReadLine();
The && and || operators are not overloadable, but you can virtually do so by overloading the & or the | along the true and false operators.
Comparison operators
For the comparison operators you need to overload them in pairs. This means that if you overload the equality (==) comparison operator you also need to overload the inequality (!=) comparison operator, otherwise you'll get a compiler error.
Here is the code for the Celsius and Farenheit temperatures:
public static bool operator == (Temperature tempA, Temperature tempB){
if(tempA.Type == tempB.Type) return tempA.Value == tempB.Value;
var tempValueA = tempA.Type == TemperatureType.Celsius ? tempA.Value : (tempA.Value - 32) * (5d / 9d);
var tempValueB = tempB.Type == TemperatureType.Celsius ? tempB.Value : (tempA.Value - 32) * (5d / 9d);
return tempValueA == tempValueB;
}
public static bool operator != (Temperature tempA, Temperature tempB){
if(tempA.Type == tempB.Type) return tempA.Value != tempB.Value;
var tempValueA = tempA.Type == TemperatureType.Celsius ? tempA.Value : (tempA.Value - 32) * (5d / 9d);
var tempValueB = tempB.Type == TemperatureType.Celsius ? tempB.Value : (tempB.Value - 32) * (5d / 9d);
return tempValueA != tempValueB;
}
Now you can use the comparison operator to evaluate directly the value of the temperatures without the need to do yourself the conversion:
var tempA = new Temperature(25.8, TemperatureType.Celsius);
var tempB = new Temperature(78.44, TemperatureType.Farentheit);
var tempAreEquals = tempA == tempB;
// Prints true
Console.WriteLine("Are temperature equals? "+ tempAreEquals);
Console.ReadLine();
Conclusion
In this entry we saw how to apply the binary operators to our custom data types, although their use cases are minimal they provide an easy and concise way to provide additional behaviors and comparison capabilities to our objects.
Stay tuned for the next and final entry of this series, in which I'll be talking about the explicit and implicit operators for casting between types as well as the indexing operator for array-like index access.
Top comments (0)