• Discover how to overload unary, binary, relational, and logical operators.. Creating Overloaded Operators Using methods such as those presented in Listing 14.2 is a perfectly acceptabl
Trang 2As you can see by the output, when Line 22 is executed, the Change_Devent is no
longer active However, theChange_Aevent handler continues to work
Caution
Summary
In today’s lesson, you learned about some of the more complicated topics within C# You
first learned about indexers Indexers can be used with a class so that you can access the
class using index notation This makes your classes “arraylike.”
You then learned about delegates You learned that delegates are like interfaces: They
state a definition for accessing but don’t actually provide the implementation Delegates
set up a format for using methods You learned that a delegate can be used to
dynami-cally call different methods with a single method call
The last part of today’s lesson focused on events You learned that code can be created to
cause an event to happen More important, you learned that code—event handlers—can
be created to react when an event happens
Q&A
Q Today’s concepts were hard How important is it to understand them?
A You can do a lot with C# without understanding the concepts presented today;
however, there is a lot more that you won’t be able to do If you plan to program
applications for Windows or other graphical environments, you will find that
events are critical And as you learned today, delegates are critical for working with
events
Trang 3Many of the C# editors, such as Visual Studio NET, will help by automaticallycreating a lot of the code for you For example, Visual Studio NET adds code formany of the standard events.
Q In today’s lesson, events were declared in properties Do they have to be declared in a property?
A No You can declare an event call within a property or a method
Q Multiple event handlers were assigned to an event Can multiple methods be assigned to a single delegate?
A Yes It is possible to assign more than one method to a single delegate so that
mul-tiple methods execute with a single call This is also called multicasting
Q What is a function pointer?
A In languages such as C and C++, there is a construct called a function pointer A
function pointer is used to accomplish the same task as a delegate A delegate,however, is type-safe and secure In addition to being used to reference methods,delegates are used by events
Workshop
The Workshop provides quiz questions to help you solidify your understanding of thematerial covered and exercises to provide you with experience in using what you’velearned Try to understand the quiz and exercise answers before continuing to tomorrow’slesson Answers are provided on the CD
Trang 43 What is the point of an indexer?
4 When declaring an indexer, what keyword is used?
5 An indexer definition is similar to which of the following:
6 What are the different steps to creating and using an event?
7 What operator is used to add an event handler?
8 What is it called when multiple event handlers are added to an event?
9 Which is true (note—None and Both are possible answers):
An event is an instantiation based on a delegate
A delegate is an instantiation based on an event
10 Where within a class can an event be instantiated?
Exercises
1 Add an indexer to the following class Use the class in a simple program
public class SimpleClass
{
int[] numbers;
public SimpleClass(int size)
{
numbers = new int[size]; // declare size elements
for ( int x = 0; x < size; x++ ) // initialize values to 0.
numbers[x] = 0;
}
}
Trang 52 Rewrite Listing 13.1 without using indexers
3 Modify Listing 13.2 so that you don’t have to declare a doITobject
4 Write a program using a delegate that sorts an array of integers You can useListing 13.2 as a starting point
5 Add an event handler to the code in Listing 13.5 This event handler should changeany lowercase vowels to uppercase
Trang 6• Revisit method and constructor overloading.
• Learn about overloading operators
• Discover how to overload unary, binary, relational, and logical operators
• Understand the difference in overloading the logical operators
• Review the individual operators that can and can’t be overloaded
Trang 7Overloading Functions Revisited
On Day 8, “Advanced Method Access,” you learned that you can overload a method tiple times The key issue with overloading a method is that you must ensure that eachtime you overload the method, it has a different signature A signature is determined bythe return type and parameters of a method For example, all of the following are differ-ent signatures:
mul-int mymethod( mul-int x, mul-int y )
int mymethod( int x )
int mymethod( long x )
int mymethod( char x, long y, long z )
int mymethod( char x, long y, int z )
On Day 8, you learned that you could overload constructors as well as regular methods.Today you go beyond overloading methods: You learn how to overload a class’s
operators
Overloading Operators
In addition to overloading constructors and accessors, many object-oriented languagesgive you the capability to overload operators C# is no exception: It enables you to over-load many of the mathematical operators—such as addition (+) and subtraction (-)—aswell as many of the relational and logical operators
Why would you want to overload these operators? You do not ever have to overload
them Sometimes, however, it can make your program’s code easier to follow and yourclasses easier to use
TheStringclass is a great example of a class that has an operator that is overloaded.Normally, the addition operator would not work on a class type, but in C#, you can actu-ally add two strings with the addition operator This addition does what you wouldexpect: It concatenates two strings For example:
Trang 8You will find that overloading operators can make some of your programs work better as
well Take a look at Listing 14.1 This listing gives you an error when you compile The
error is shown in the listing’s output
This listing is not a great example of using operator overloading; however, it
is simple so that you can focus on the concepts instead of trying to stand the code in a complex listing A few of the later listings in today’s les- son are much more practical.
under-Note
L ISTING 14.1 over1a.cs—A Program with a Problem
1: // over1a.cs - A listing with a problem
10: public AChar() { this.ch = ‘ ‘; }
11: public AChar(char val) { this.ch = val; }
12:
13: public char ch
14: {
15: get{ return this.private_ch; }
16: set{ this.private_ch = value; }
25: AChar aaa = new AChar(‘a’);
26: AChar bbb = new AChar(‘b’);
Trang 9The following errors are generated when you try to compile this listing:
over1a.cs(30,13): error CS0019: Operator ‘+’ cannot be applied to
➥operands of type ‘AChar’ and ‘int’
over1a.cs(31,13): error CS0019: Operator ‘-’ cannot be applied to
➥operands of type ‘AChar’ and ‘int’
This listing is easy to follow A class is created named AChar This class is notpractical, but its simplicity makes it easy to use as an illustration for overloading TheACharclass stores a single character The class has two constructors in Lines 10–11.The first is called when no arguments are provided; it sets the character value stored in anewly instantiated object to a space The second constructor takes a single character that
is placed in a new object’s private character variable The class uses an accessor in Lines 13–17 to do the actual setting of the character value
TheACharclass is used in the myAppClassclass In Lines 25–26, two ACharobjects are ated.aaawill contain a, andbbbwill contain b In Line 33, these values are printed InLine 30, the value of 3is added to aaa What would you expect would happen when youadd3to an ACharobject? Note that this is not a type charobject or even a numeric object
cre-It is an ACharobject
This listing is trying to add 3to the actual object, not to a member of the object Theresult, as you can see by the compiler output, is an error
In Line 31, the value of 1is subtracted from an ACharobject An error is produced
because you can’t add or subtract from an object like this If Lines 30–31 had worked,Line 33 would have printed their values
You can make the addition work by manipulating an object’s members instead of theclass itself Changing Lines 30–31 to the following allows the listing to compile:
aaa.ch = (char) (aaa.ch + 3);
bbb.ch = (char) (bbb.ch - 1);
Although this works, it is not the ultimate solution There is too much casting, and thecode is not as simple as it could be Another solution to make this clear is to add meth-ods to the class that allow addition and subtraction—or other types of operations—to bedone with the class’s objects Listing 14.2 presents this approach
OUTPUT
A NALYSIS
Trang 10L ISTING 14.2 over1b.cs—Operators for Mathematical Functions
1: // over1b.cs - Using methods for mathematic operations
10: public AChar() { this.ch = ‘ ‘; }
11: public AChar(char val) { this.ch = val; }
12:
13: public char ch
14: {
15: get{ return this.private_ch; }
16: set{ this.private_ch = value; }
17: }
18:
19: static public AChar Add ( AChar orig, int val )
20: {
21: AChar result = new AChar();
22: result.ch = (char)(orig.ch + val);
23: return result;
24: }
25: static public AChar Subtract ( AChar orig, int val )
26: {
27: AChar result = new AChar();
28: result.ch = (char)(orig.ch - val);
37: AChar aaa = new AChar(‘a’);
38: AChar bbb = new AChar(‘b’);
Trang 11Original value: a, b Final values: d, a
This listing is better than the last listing—this one compiles! It also provides tines for doing mathematical operations on the class This is accomplished withthe static methods AddandSubtractdeclared in Lines 19–24 and 25–30, respectively TheAddmethod increments the original ACharcharacter value (ch) by the number speci-fied In the myAppClassclass, the AChar.Addmethod is called to increment aaaby3, whichresults in an abecoming a d The Addmethod returns a new ACharclass that can overwritethe original In this way, a number can be added to the class and returned to overwritethe original value The Subtractmethod works in the same manner, except that the ch
rou-value is decremented by the given number
This listing is relatively simple If there were other data members as a part of the class,theAddandSubtractoperations would become more complex; however, they would alsobecome more valuable Consider a few examples:
• A depositclass that contains members for the person making the deposit, anaccount number, and the value being deposited In this case, the Addmethod couldmanipulate the value being deposited
• A currencyclass that contains an enumeration value that indicates the type of rency and multiple numeric values to store different money types, such as dollarsand cents
cur-• A salaryclass that contains an employee name, the employee ID number, the date
of the last salary increase, and the actual salary for the employee
Creating Overloaded Operators
Using methods such as those presented in Listing 14.2 is a perfectly acceptable way toincrement and decrement values of a class Sometimes, however, overloading an operatormakes the class easier to use The three examples given are such cases, as is the String
concatenation example from earlier
TheACharclass is probably not a good class to overload the operators with Simply put,
if you overload an operator, it should be obvious to everyone using the class what theoverloaded operator is doing Consider the following lines of code What would youexpect the results to be? What would everyone else expect the results to be?
Trang 12TheSalaryand the Depositlines should be obvious The MyChar + 3line might seem
obvious, but is it? MyChar + ‘a’is even more cryptic The +operator could be overloaded
for all of these cases, thus making these examples work The MyCharexample would be
better using a descriptive named method instead of overloading an operator
A number of operators can be overloaded This includes the basic binary mathematics
operators, most of the unary operators, the relational operators, and the logical operators
Overloading the Basic Binary Mathematical Operators
The binary operators are operators that use two values These operators include addition
(+), subtraction (-), multiplication (*), division (/), and modulus (%) All of these can be
overloaded within your classes The total list of binary operators that can be overloaded
The format for overloading a binary operator is similar to the format for creating
meth-ods The general format for overloading an operator is shown here:
public static return_type operator op ( type x, type y )
{
return return_type;
}
Here,return_typeis the data type that is being returned by the overloaded operator For
theACharclass in the earlier example,return_typewas the class type—AChar The return
type is preceded by the publicandstaticmodifiers An overloaded operator must always
be public so that it can be accessed It also must always be static so that it can be
accessed at the class level rather than at an individual object level
The term operatoris then used to indicate that this is an operator-overloading method
The operator being overloaded (op) then is presented If you were overloading the
Trang 13addition operator, for example, this would be a plus sign Finally, the parameters for theoperation are presented.
In this example, a binary operator is being overloaded, so there are two parameters One
of the parameters must be of the type of the class whose operator is being overloaded.The other parameter’s type can be of any type When setting up operator overloading,you will often set these two types as the same It is perfectly acceptable to make the sec-ond type a different type as well In fact, if you are overloading an operator, you should
be sure to set up overloaded methods for any possible data types that might be added tothe original class
Looking back at the ACharclass, the following is the method header for overloading theaddition operator so that you can add an integer value to an ACharvalue:
public static AChar operator+ (AChar x, int y)
Althoughxandyare used as the parameter names, you can use any variable names thatyou want An integer value is the second parameter because that is what was added to the
ACharobjects in the earlier listings Listing 14.3 presents the ACharclass one more time.This time, however, the addition and subtraction operators are overloaded to allow aninteger to be added to an AChar
You may have noticed that the format description earlier had a space between the word operator and the opsign In the example just presented for the AChar class, there is no space; the operator is connected to the word
operator Either format works
Note
L ISTING 14.3 over1c—Overloading the Binary Operators
1: // over1c.cs - Overloading an operator
10: public AChar() { this.ch = ‘ ‘; }
11: public AChar(char val) { this.ch = val; }
Trang 1421: AChar result = new AChar();
22: result.ch = (char)(orig.ch + val);
23: return result;
24: }
25: static public AChar operator- ( AChar orig, int val )
26: {
27: AChar result = new AChar();
28: result.ch = (char)(orig.ch - val);
37: AChar aaa = new AChar(‘a’);
38: AChar bbb = new AChar(‘b’);
Lines 19–30 contain the overloading of the addition and subtraction operators of
theACharclass In Line 19, the overloading follows the format presented earlier
and an AChartype is returned The first type being added is also an AChar
In this example, an integer value is being added to an AChartype You could have used
anotherACharobject or any other type that would make sense instead of the integer You
can overload the addition operator multiple times, each time adding a different data type
to the AChartype, as long as the resulting overloads have unique signatures In fact, you
will need to overload any types that might be used
L ISTING 14.3 continued
OUTPUT
A NALYSIS
Trang 15The overloaded addition operator’s functionality is presented in Lines 21–23 A new
ACharobject is instantiated in Line 21 The chvalue within this new ACharobject isassigned a value based upon the values received with the addition operator When thisvalue is updated, the new ACharobject,result, is returned The code in this method could
be changed to anything you want; however, it should be related to the values received bythe addition operator
The subtraction operator is set up in the same manner as the addition operator In anexercise at the end of today’s lesson, you create a second overloaded method for the sub-traction operator The second method takes two ACharvalues and returns the number ofpositions between them
This listing overloaded only the addition and subtraction operators Overloading the tiplication, division, modulus, and other binary operators is done in the same way
mul-Overloading the Basic Unary Mathematical Operators
The unary operators work with only one element The unary operators that can be loaded are listed here:
over-+
- ++
!
~ true false
The unary operators are overloaded similarly to the binary operators The difference isthat only one value is declared as a parameter This single value is of the same data type
as the class containing the overload A single parameter is all that is passed because aunary operator operates on a single value Two examples are presented in Listings 14.4and 14.5 Listing 14.4 presents the positive (+) and negative (-) unary operators Theseare used with the ACharclass that you’ve already seen A positive ACharcapitalizes thecharacter A negative ACharconverts the character to lowercase
Trang 16Listing 14.5 uses the increment and decrement ( ) operators This listing increments the
character to the next character value or decrements the character to the preceding value
Note that this is moving through the character values, so incrementing Zor decrementing
Awill take you to a nonletter character You could add logic, however, to prevent the
incrementing or decrementing past the end or beginning of the alphabet
L ISTING 14.4 over2.cs—Overloading the + and - Unary Operators
11: public AChar() { this.ch = ‘ ‘; }
12: public AChar(char val) { this.ch = val; }
13:
14: public char ch
15: {
16: get{ return this.private_ch; }
17: set{ this.private_ch = value; }
18: }
19:
20: static public AChar operator+ ( AChar orig )
21: {
22: AChar result = new AChar();
23: if( orig.ch >= ‘a’ && orig.ch <=’z’ )
24: result.ch = (char) (orig.ch - 32 );
32: AChar result = new AChar();
Again, the + and – operators to change the case of a character are not ous functions Although these operations make good examples, they aren’t good in practical usage because they are not obvious Again, you would be better served using methods with descriptive names.
obvi-Caution
Trang 1733: if( orig.ch >= ‘A’ && orig.ch <=’Z’ ) 34: result.ch = (char) (orig.ch + 32 ); 35: else
47: AChar aaa = new AChar(‘g’);
48: AChar bbb = new AChar(‘g’);
49: AChar ccc = new AChar(‘G’);
50: AChar ddd = new AChar(‘G’);
51:
52: Console.WriteLine(“ORIGINAL:”);
53: Console.WriteLine(“aaa value: {0}”, aaa.ch); 54: Console.WriteLine(“bbb value: {0}”, bbb.ch); 55: Console.WriteLine(“ccc value: {0}”, ccc.ch); 56: Console.WriteLine(“ddd value: {0}”, ddd.ch); 57:
69: }
ORIGINAL:
aaa value: g bbb value: g ccc value: G ddd value: G
FINAL:
aaa value: G bbb value: g
L ISTING 14.4 continued
OUTPUT
Trang 18ccc value: G
ddd value: g
As you can see by the output of Listing 14.4, using the +operator changes a
low-ercase letter to upplow-ercase It has no effect on a letter that is already upplow-ercase
Using the -operator does the opposite: It changes an uppercase letter to lowercase It has
no effect on a character that is lowercase
Lines 20–39 contain the overloaded operator methods You know that these are unary
overloaded operator methods because they each have only one parameter (see Lines 20
and 30) The code within these overloaded operators is relatively straightforward The
code checks to see whether the original character is an alphabetic character that is either
uppercase (Line 33) or lowercase (Line 24) If the character is one of these, it is changed
to the other case by either adding 32 or subtracting 32
A NALYSIS
Remember that characters are stored as numeric values The letter A is stored as 65 The letter a is stored as 97 Each letter of the same case is stored sequentially afterward
Note
Listing 14.4 overloaded the unary positive and negative operators; Listing 14.5 overloads
the increment and decrement operators
L ISTING 14.5 over2b.cs—Overloading the Increment and Decrement Operators
10: public AChar() { this.ch = ‘ ‘; }
11: public AChar(char val) { this.ch = val; }
12:
13: public char ch
14: {
15: get{ return this.private_ch; }
16: set{ this.private_ch = value; }
17: }
18:
19: static public AChar operator++ ( AChar orig )
20: {
Trang 1921: AChar result = new AChar();
38: AChar aaa = new AChar(‘g’);
39: AChar bbb = new AChar(‘g’);
This listing is similar to the previous listing Instead of overloading the -and+
operators, this listing overloads the and++operators When overloaded, theseoperators can be used with objects of the given class You see this in Lines 43, 44, 48,and 49 The other unary operators can be overloaded in the same way
L ISTING 14.5 continued
OUTPUT
A NALYSIS
Trang 20Overloading the Relational and Logical Operators
The relational operators can also be overloaded This includes the following operators:
These differ from the previous operators in how they are declared Instead of returning a
value of the class type, these operators return a Boolean value This should make sense:
The idea of these operators is to compare two values and determine a truth about them
Listing 14.6 uses a more realistic class to illustrate a couple of the relational operators
being overloaded This class defines a Salaryvalue You will notice that the ==and the !=
are not illustrated in this listing; they require a slightly different approach, which is
cov-ered in the next section
L ISTING 14.6 over3.cs—Overloading the Relational Operators
1: // over3.cs - Overloading Relational Operators
11: public Salary() { this.amount = 0; }
12: public Salary(int val) { this.amount = val; }
13:
14: public int amount
15: {
16: get{ return this.AMT; }
17: set{ this.AMT = value; }
18: }
19:
20: static public bool operator < ( Salary first, Salary second )
21: {
Trang 2278: Salary mySalary = new Salary(24000);
79: Salary yourSalary = new Salary(24000);
80: Salary PresSalary = new Salary(200000);
81:
82: Console.WriteLine(“Original values: “);
83: Console.WriteLine(“ my salary: {0}”, mySalary);
84: Console.WriteLine(“ your salary: {0}”, yourSalary);
85: Console.WriteLine(“ a Pres’ salary: {0}”, PresSalary);
86: Console.WriteLine(“\n -\n”);
87:
88: if ( mySalary < yourSalary )
89: Console.WriteLine(“My salary less than your salary”);
90: else if ( mySalary > yourSalary )
91: Console.WriteLine(“My salary is greater than your salary”);
a Pres’ salary: 200000
-Our Salaries are the same
I don’t make as much as a president.
This listing creates a Salaryclass that contains a person’s salary Although this
example doesn’t include it, you could also include information such as the last
time the person received a raise, the amount of the raise, and more Regardless of what
you include, the basic information that you would expect from this class is a person’s
salary
L ISTING 14.6 continued
OUTPUT
A NALYSIS
Trang 23For this example, several of the relational operators are overloaded Each is overloaded inthe same manner, so only one needs to be reviewed here Line 20 overloads the less-thanoperator (<).
The return type is a Boolean (type bool) The result of the method is to return trueor
false The method also receives two Salaryobjects as parameters: the value before andthe value after the less-than sign when it is used in code:
first < second
Using these two values, you can make the determinations that fit for the class In thiscase, a check is done in Line 24 to see whether the first Salaryobject’s amountis less thanthe second Salaryobject’s amount If so,trueis set for a return value If not,falseis setfor the return value Line 29 then returns the value
In the myAppClassclass, using the overloaded relational operators is no different thanusing relational operators with the basic data types You can easily compare one salary toanother, as done in Lines 88, 90, and 95
Another part of this listing that needs to be covered is not related to operator ing In Lines 68–71, the ToString()method is overridden by using the overridekeyword.TheToStringmethod was inherited automatically from the base class,Object Rememberfrom the days on inheritance that all classes derive from Objectautomatically As such,all classes contain the functionality of methods that were contained in Object Thisincludes the ToStringmethod
overload-TheToStringmethod can be overridden in any class It should always return a string resentation of a class In the case of a Salaryclass that could contain lots of members,you could return a number of possible items Returning a string representation of theactual value makes the most sense, however This is exactly what Line 70 does
rep-More important, by overloading the ToStringmethod (Lines 83–85), you gain the bility to “print” the class When you display the class as shown in these lines, the
capa-ToStringmethod is automatically called
Overloading the Logical Operators
Overloading the equality and inequality logical operators takes more effort than loading the other relational operators First, you can’t overload just one of these; if youwant to overload one, you must overload both Additionally, if you want to overloadthese operators, you must also overload two methods,Equals()andGetHashCode() LiketheToStringmethod, these methods are a part of the base object (Object) and are auto-matically inherited when you create a class These methods must be overloaded becausethe logical operators use them behind the scenes
Trang 24When comparing two objects of the same class, you should define anEqualsmethod that
overrides the base class’s Equalsmethod This method takes the following format:
public override bool Equals(object val)
{
// determine if classes are equal or not
// return (either true or false)
}
This method can be used to see whether one object is equal to another You can do
what-ever logic that you want within this method This might include checking a single value
or checking multiple values For example, are two salaries equal if the amount is equal?
If the Salaryclass includes hire dates, would two salaries that are of the same annual
amount be equal if the hire dates were different? These are the type of decisions that you
must make to code the logic within the Equalsmethod
TheGetHashCodemust also be overridden if you want to override the == and!=operators
TheGetHashCodemethod returns an integer value used to identify a specific instance of a
class In general, you will not want to make any changes to this method You can
over-ride this method and return the hash code of the current instance by including the
follow-ingoverridemethod:
public override int GetHashCode()
{
return this.ToString().GetHashCode();
}
After you have overridden the EqualsandGetHashCodemethods, you must define the
over-load methods for ==and!= This is done with the same initial method structure as used
with the relational operators One difference is that you should use the Equalsmethod
instead of repeating any comparison code In Listing 14.7, the !=operator basically calls
theEqualsmethod and returns the not (!) value of it
The Equals method actually uses the return values from the GetHashCode
method to determine whether two objects are equal.
Trang 257: public class Salary
8: {
9: private int AMT;
10:
11: public Salary() { this.amount = 0; }
12: public Salary(int val) { this.amount = val; }
13:
14: public int amount
15: {
16: get{ return this.AMT; }
17: set{ this.AMT = value; }
Trang 2667: Salary mySalary = new Salary(24000);
68: Salary yourSalary = new Salary(24000);
69: Salary PresSalary = new Salary(200000);
My salary equals your salary
My salary does not equal a president’s salary
Most of the code in this listing was analyzed before the listing You’ll find the
overloadedEqualsmethod in Lines 20–30 The overloaded GetHashCodemethod is
in Lines 32–35 For fun, you can remove one of these two methods and try to compile
the listing; you will see that your listing will generate errors without them
L ISTING 14.7 continued
OUTPUT
A NALYSIS
Trang 27Line 27 starts the method for overloading the ==operator Earlier, I stated that you shoulduse the Equalsmethod for comparing classes This is exactly what the overloaded ==
method is doing: It calls the Equalsmethod and returns the value from it The !=methoddoes the same thing in Lines 45–52, except that the value is changed by using the !oper-ator
In the Mainmethod of the myAppClassclass, using the ==and!=operators is as easy asusing the other overloaded operators If you compare two classes, you’ll receive aresponse of trueorfalse
When overloading the logical operators, == and != , you must always load both You can’t overload just one.
over-Caution
Summarizing the Operators to Overload
A number of operators can be overloaded To repeat an earlier point, you should load operators only when the resulting functionality will be clear to a person using theclass If in doubt, you should use regular methods instead The operators that are avail-able to overload are presented in Table 14.1 The operators that cannot be overloaded arepresented in Table 14.2
sizeof typeof checked unchecked
You also cannot overload parentheses or any of the compound operators (+=,-=, and soforth) The compound operators use the binary overloaded operators
The only operators that are left are the brackets,[] As you learned earlier in the book,these are overloaded by using indexers
Trang 28Summary
Today’s lessons covered another OOP topic: overloading operators Although many
peo-ple believe that operator overloading is compeo-plex, as you saw today, it can be quite
sim-ple You learned to overload the unary, binary, relational, and logical operators The final
section of today’s lessons presented two tables containing the operators that can and
can’t be overloaded
With today’s lessons, you have learned nearly all the basics of C# This includes having
learned nearly all the basic constructs of the language, as well as their use Over the next
several days, you will learn about classes that have been created as part of the NET
Framework These are classes that you can use in your C# applications You’ll come back
to a number of additional advanced C# language topics Although you have all the
build-ing blocks needed to create complex C# applications, there are a few additional advanced
topics worth being exposed to These are covered on Day 21, “A Day for Reflection and
Attributes.”
Q&A
Q Which is better, using methods such as Add() or overloading operators?
A Either works Many people expect operators to be overloaded when working with
advanced languages such as C++ and C# As long as it is clear what should be
expected when two classes are added or manipulated with an operator, you should
consider overloading the operator In the end, it can actually make your code easier
to follow and understand
Q Why can’t compound operators such as += be overloaded?
A This was actually answered in today’s lesson The compound operators are always
broken out into:
This means the overloaded binary operator can be used If you overload the
addition operator (+), you essentially also overload the compound addition
operator (+=)
Trang 29Q I want a different method for postfix and prefix versions of the decrement and increment operators What do I do?
A Sorry—C# doesn’t support this You get to define only a single overloaded method
for the increment and decrement operators
Workshop
The Workshop provides quiz questions to help you solidify your understanding of thematerial covered and exercises to provide you with experience in using what you’velearned Try to understand the quiz and exercise answers before continuing to tomorrow’slesson Answers are provided on the CD
Quiz
1 How many times can a single operator be overloaded in a single class?
2 What determines how many times an operator can be overloaded?
3 What method or methods must be overloaded to overload the equality operator(==)?
4 Which of the following are good examples of using overloaded operators?
a Overloading the plus operator (+) to concatenate two string objects
b Overloading the minus operator (-) to determine the distance between two
MapLocationobjects
c Overloading the plus operator (+) to increment an amount once, and ing the ++operator to increment the amount twice
increment-5 How do you overload the /=operator?
6 How do you overload the []operator?
7 What relational operators can be overloaded?
8 What unary operators can be overloaded?
9 What binary operators can be overloaded?
10 What operators cannot be overloaded?
11 What modifiers are always used with overloaded operators?
Exercises
1 What would the method header be for the overloaded addition operator used to addtwo type XYZobjects?
Trang 302 Modify Listing 14.3 Add an additional subtraction overloaded method that takes
two ACharvalues The result should be the numerical difference between the
char-acter values stored in the two ACharobjects
3 Bug Buster: Does the following code snippet have a problem? If so, what is the
problem? If not, what does this snippet do?
static public int operator >= ( Salary first, Salary second )
4 Modify Listing 14.7 to include a method that will compare a salary to an integer
value Also add a method to compare a salary to a longvalue
Trang 32Week in Review
You’ve succeeded in making it through the second week of
learning C#! At this point, you have learned most of the key
foundational topics in C#
The following listing pulls together many of these concepts
into a program that is a little more functional than the
exam-ples in the lessons This program is longer, but as you will
see, it is a little more fun
This listing presents a limited blackjack, or “21,” card game
This program displays the cards in your hand and the first
card in the computer dealer’s hand The idea of blackjack is
to accumulate cards totaling as close to 21 as you can without
going over Face cards (jacks, queens, and kings) are worth
10 points, and the other cards are worth their basic value An
ace can be worth 1 point or 11 points—you decide
The computer dealer must have a total of at least 17 If the
computer’s hand is less than 17, the dealer must draw another
card If the dealer goes over 21, it busts If you go over 21,
you bust and the computer automatically wins
L ISTING WR2.1 CardGame.cs—The Game of Blackjack
Trang 3337: {
38: public CardSuit suit; // 1 - 4
39: public CardValue val; // 1 - 13
Trang 3459: public override string ToString()
80: // Initialize the cards in the deck
81: Cards[0].val = 0; // card 0 is set to 0
89: currcard = (valctr) + ((suitctr - 1) * 13);
90: cards[currcard].val = (CardValue) valctr;
91: cards[currcard].suit = (CardSuit) suitctr;
Trang 35108: sort1 = (int) ((rnd.NextDouble() * 52) + 1); 109: sort2 = (int) ((rnd.NextDouble() * 52) + 1); 110:
111: tmpcard = this.Cards[sort1];
112: this.Cards[sort1] = this.Cards[sort2]; 113: this.Cards[sort2] = tmpcard;
140: class CardGame
141: {
142: static Deck mydeck = new Deck();
143: static Card [] pHand = new Card[10];
144: static Card [] cHand = new Card[10];
Trang 38276: Console.Write(“\n\nDo you want to play again? “);
277: string answer = Console.ReadLine();
Trang 39302: bool cont = true;
303: bool retval = true;
Card 1: Jack of hearts - Player Total = 10
Trang 40H = Hit, S = Stay h
Player’s Hand:
Card 1: four of clubs
Card 2: six of hearts
Card 3: King of diamonds
Card 1: three of clubs
Card 2: Jack of spades
Card 1: three of clubs
Card 2: Jack of spades
Card 3: five of hearts
Dealer’s Hand: