struct
Method-call notation can be cumbersome for certain kinds of operations, such as arithmetic. In these cases, it would be convenient to use C#’s rich set of built-in operators instead. This section shows how to create operators that work with objects of your own types—via a process called operator overloading.
You can overload most operators. Some are overloaded more frequently than others, especially the arithmetic operators, such as +
and -
, where operator notation is more natural than calling methods. For a list of overloadable operators, see
https://msdn.microsoft.com/library/8edha89s
struct
To demonstrate operator overloading, we’ll define type ComplexNumber
(Section 10.13.2). Complex numbers have the form
realPart +
imaginaryPart * i
where i
is ComplexNumber
as a value type by using a struct
(short for “structure”) rather than a class
. C#’s simple types like int
and double
are actually aliases for struct
types—an int
is defined by the struct
System.Int32
, a long
by System.Int64
, a double
by System.Double
and so on. The operator overloading techniques shown in Section 10.13.2 also can be applied to classes.
struct
TypeMicrosoft recommends using classes for most new types, but recommends a struct
if:
the type represents a single value—a complex number represents one number that happens to have a real part and an imaginary part.
the size of an object is 16 bytes or smaller—we’ll represent a complex number’s real and imaginary parts using two double
s (a total of 16 bytes).
For the complete list of struct
recommendations, see
https://msdn.microsoft.com/library/ms229017
ComplexNumber
Value type ComplexNumber
(Fig. 10.14) overloads the plus (+
), minus (-
) and multiplication (*
) operators to enable programs to add, subtract and multiply instances of class ComplexNumber
using common mathematical notation. Lines 9–10 define getter-only auto-implemented properties for the ComplexNumber
’s Real
and Imaginary
components.
Lines 13–17 define a ComplexNumber
constructor that receives parameters to initialize the Real
and Imaginary
properties. Unlike a class
, you cannot define a parameterless constructor for a struct
—the compiler always provides a default constructor that initializes the struct
’s instance variables to their default values. Also, struct
s cannot specify initial values in instance variable or property declarations.
Lines 24–28 overload the plus operator (+
) to add ComplexNumber
s. Keyword operator
, followed by an operator symbol (such as +
), indicates that a method overloads the specified operator. Overloaded operator methods are required to be public
and static
.
Methods that overload binary operators must take two arguments—the first is the left operand and the second is the right operand. Class ComplexNumber
’s overloaded +
operator takes two ComplexNumber
s as arguments and returns a ComplexNumber
that represents the sum of the arguments. The method’s body adds the ComplexNumber
s and returns the result as a new ComplexNumber
.
We do not modify the contents of either of the original operands passed as arguments x
and y
. This matches our intuitive sense of how this operator should behave—adding two numbers does not modify either of the original values. Lines 31–43 declare similar overloaded operators to subtract and multiply ComplexNumber
s.
Overload operators to perform the same function or similar functions on objects as the operators perform on objects of simple types. Avoid nonintuitive use of operators.
At least one parameter of an overloaded operator method must be of the type in which the operator is overloaded. This prevents you from changing how operators work on simple types.
Though you cannot overload the arithmetic assignment operators (e.g., +=
and -=
), C# allows you to use them with any type that declares the corresponding arithmetic operator (e.g., +
and -
).
ComplexTest
Class ComplexTest
(Fig. 10.15) demonstrates the overloaded ComplexNumber
operators +
, -
and *
. Lines 10–21 prompt the user to enter the real and imaginary parts of two complex numbers, then use this input to create two ComplexNumber
objects for use in calculations.
Lines 25–27 add, subtract and multiply x
and y
with the overloaded operators (in string
-interpolation expressions), then output the results. In line 25, we use the +
operator with ComplexNumber
operands x
and y
. Without operator overloading, the expression x
+ y
wouldn’t make sense—the compiler wouldn’t know how to add two ComplexNumber
objects. This expression makes sense here because we’ve defined the +
operator for two ComplexNumber
s in lines 24–28 of Fig. 10.14. When the two ComplexNumber
s are “added” in line 25 of Fig. 10.15, this invokes the operator+
declaration, passing the left operand as the first argument and the right operand as the second argument. When we use the subtraction and multiplication operators in lines 26–27, their respective overloaded operator declarations are invoked similarly.
Each calculation’s result is the new ComplexNumber
object returned by the corresponding overloaded operator method. When this new object is placed in a string
-interpolation expression, its ToString
method (Fig. 10.14, lines 20–21) is implicitly invoked. The expression x
+
y
in line 25 of Fig. 10.15 could be rewritten to explicitly invoke the ToString
method of the resulting ComplexNumber
object, as in:
(x + y).ToString()