Operator Overloading
Objectives
Discuss operator overloading
definition
use
advantages
limitations
Present type conversion operators
Arithmetic operations
Could define a method to perform arithmetic operation
supply as part of class or struct
struct Point
{
int x;
int y;
public static Point Add(Point p, Point q)
{
return new Point(p.x + q.x, p.y + q.y);
}
...
add points
}
Point a = new Point(1, 2);
Point b = new Point(3, 4);
invoke Add
Point c = Point.Add(a, b);
3
Operator overloading
Can overload operators to work with class and struct types
use keyword operator
follow with symbol
struct Point
{
int x;
int y;
overload +
public static Point operator+(Point p, Point q)
{
return new Point(p.x + q.x, p.y + q.y);
}
...
}
Using overloaded operator
Overloaded operator used like operators for other types
compiler translates into method call
Point a = new Point(1, 2);
Point b = new Point(3, 4);
use operator+
Point c = a + b;
Advantages of operator overloading
Operator overloading yields advantages for user code
concise
readable
takes advantage of user's existing knowledge of symbol
Point a = new Point(1, 2);
Point b = new Point(3, 4);
operator
method
Point c = a + b;
Point d = Point.Add(a, b);
Binary operators
Binary operators take two parameters
struct Point
{
int x;
int y;
binary +
public static Point operator+(Point p, Point q)
{
return new Point(p.x + q.x, p.y + q.y);
}
binary -
public static Point operator-(Point p, Point q)
{
return new Point(p.x - q.x, p.y - q.y);
}
...
}
7
Unary operators
Unary operators take single parameter
struct Point
{
int x;
int y;
unary +
public static Point operator+(Point p)
{
return new Point(p.x, p.y);
}
unary -
public static Point operator-(Point p)
{
return new Point(-p.x, -p.y);
}
...
}
8
Mixed types
Can mix parameter types
separate method for each combination of parameter type/order
Point*int
struct Point
{
public static Point operator*(Point p, int a)
{
return new Point(p.x * a, p.y * a);
}
public static Point operator*(int a , Point p)
{
return new Point(a * p.x, a * p.y);
}
...
int*Point
Equality
Can overload equality and inequality
should ensure Equals method has same semantics
equality
inequality
struct Point
{
public static bool operator==(Point p, Point q)
{
return p.x == q.x && p.y == q.y;
}
public static bool operator!=(Point p, Point q)
{
return !(p == q);
}
...
}
Point a = new Point(1, 2);
Point b = new Point(3, 4);
compare points
if (a == b) ...
10
Operator pairs
Some operators are required to be present in pairs
== and !=
> and <
>= and <=
true and false
equality
error, must also
provide inequality
struct Point
{
public static bool operator==(Point p, Point q)
{
return p.x == q.x && p.y == q.y;
}
...
}
11
Compound assignment
Compound assignment operator provided automatically
when corresponding binary operator overloaded
define binary+
struct Point
{
public static Point operator+(Point p, Point q)
{
return new Point(p.x + q.x, p.y + q.y);
}
...
}
Point a = new Point(1, 2);
Point b = new Point(3, 4);
Point c;
get operator+
get operator+=
c = a + b;
c += b;
12
Method format
Overloaded operator must be member of class or struct
Must have specific modifiers
public
static
struct Point
{
int x;
int y;
required
modifiers
public static Point operator+(Point p, Point q)
{
return new Point(p.x + q.x, p.y + q.y);
}
...
}
13
Parameter types
At least one parameter must be of enclosing type
prevents redefinition of operators on existing type
struct Point
{
int x;
int y;
public static Point operator+(int x, int y)
{
return new Point(x, y);
}
...
error
14
Limitations
Only some operators can be overloaded
unary: + - ! ~ ++ -- true false
binary: + - * / % & | ^ << >> == != > < >= <=
Cannot
create new operators
change precedence
change associativity
change number of arguments
overload prefix/postfix versions separately
pass parameters ref or out
15
Cross language
Not all .NET languages support operator overloading
operators therefore not available to clients in all languages
should provide regular method in addition to operator
provide operator
struct Point
{
public static Point operator+(Point p, Point q)
{
return Add(p, q);
}
public static Point Add(Point p, Point q)
{
return new Point(p.x + q.x, p.y + q.y);
}
...
provide method
16
Type conversion operators
Can overload the type conversion operators
implement user defined type converters
invoke automatically or using cast syntax
Rational: 1/2
double: 0.5
int: 3
Rational: 3/1
Polar: (1, 3.14)
Cartesian: (-1, 0)
17
Converter syntax
Define converter using keyword operator
operator name is destination type of conversion
parameter is source of conversion
struct Cartesian
{
...
explicit
public static
operator Cartesian(Polar p) { ... }
implicit
}
required required choose one required destination
source
18
Implementing converter
Converter should create and return object of destination type
using data in source
struct Cartesian
{
int x;
int y;
public static explicit operator Cartesian(Polar p)
{
Cartesian c = new Cartesian();
create object of
destination type
c.x = p.r * Math.Cos(p.theta);
c.y = p.r * Math.Sin(p.theta);
convert data
return c;
return new object
}
...
}
19
Converter uses
Converter can be used whenever conversion required
assignment
parameter passing
method return
20
Explicit
Explicit converters must be invoked using cast
safest choice
requires user to acknowledge type conversion with cast
explicit converter
struct Cartesian
{
public static explicit operator Cartesian(Polar p)
{
...
}
...
}
Polar p = new Polar(1, Math.PI);
cast required
Cartesian c = (Cartesian)p;
21
Implicit
Implicit converter automatically used by compiler as needed
makes user code minimal
but can make code more difficult to understand
often recommended only if no information is lost in conversion
implicit converter
struct Cartesian
{
public static implicit operator Cartesian(Polar p)
{
...
}
...
}
Polar p = new Polar(1, Math.PI);
no cast required
Cartesian c = p;
22
Limitations
Several limitations on conversion operators
must be public
must be static
can have only single parameter
parameter can not be passed ref or out
parameter or return type must be same as enclosing type
23
Summary
C# allows many operators to be overloaded
many restrictions help avoid many tricky cases
Can overload type conversion operators
create user defined type converter
24