microsoft visual c 2008 step by step phần 4 pps

67 288 0
microsoft visual c 2008 step by step phần 4 pps

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Chapter 9 Creating Value Types with Enumerations and Structs 175 data values where it’s just as or nearly as effi cient to copy the value as it would be to copy an address. Use classes for more complex data so that you have the option of copying only the address of the actual value when you want to improve the effi ciency of your code. Understanding Structure and Class Differences A structure and a class are syntactically very similar, but there are a few important differ- ences. Let’s look at some of these differences:  You can’t declare a default constructor (a constructor with no parameters) for a struc- ture. The following example would compile if Time were a class, but because Time is a structure, it does not: struct Time { public Time() { } // compile-time error } The reason you can’t declare your own default constructor for a structure is that the compiler always generates one. In a class, the compiler generates the default con- structor only if you don’t write a constructor yourself. The compiler-generated default constructor for a structure always sets the fi elds to 0, false, or null—just as for a class. Therefore, you should ensure that a structure value created by the default constructor behaves logically and makes sense with these default values. If you don’t want to use these default values, you can initialize fi elds to different values by providing a nonde- fault constructor. However, if you don’t initialize a fi eld in your nondefault structure constructor, the compiler won’t initialize it for you. This means that you must explic- itly initialize all the fi elds in all your nondefault structure constructors or you’ll get a compile-time error. For example, although the following example would compile and silently initialize seconds to 0 if Time were a class, because Time is a structure, it fails to compile: struct Time { public Time(int hh, int mm) { hours = hh; minutes = mm; } // compile-time error: seconds not initialized private int hours, minutes, seconds; } 176 Part II Understanding the C# Language  In a class, you can initialize instance fi elds at their point of declaration. In a structure, you cannot. The following example would compile if Time were a class, but because Time is a structure, it causes a compile-time error: struct Time { private int hours = 0; // compile-time error private int minutes; private int seconds; } The following table summarizes the main differences between a structure and a class. Question Structure Class Is this a value type or a reference type? A structure is a value type. A class is a reference type. Do instances live on the stack or the heap? Structure instances are called values and live on the stack. Class instances are called objects and live on the heap. Can you declare a default constructor? No Yes If you declare your own constructor, will the compiler still generate the default constructor? Yes No If you don’t initialize a fi eld in your own constructor, will the compiler automati- cally initialize it for you? No Yes Are you allowed to initialize instance fi elds at their point of declaration? No Yes There are other differences between classes and structures concerning inheritance. These differences are covered in Chapter 12, “Working with Inheritance.” Now that you know how to declare structures, the next step is to use them to create values. Declaring Structure Variables After you have defi ned a structure type, you can use it in exactly the same way as any other type. For example, if you have defi ned the Time structure, you can create variables, fi elds, and parameters of type Time, as shown in this example: struct Time { private int hours, minutes, seconds; } Chapter 9 Creating Value Types with Enumerations and Structs 177 class Example { public void Method(Time parameter) { Time localVariable; } private Time currentTime; } Note You can create a nullable version of a structure variable by using the ? modifi er. You can then assign the null value to the variable: Time? currentTime = null; Understanding Structure Initialization Earlier in this chapter, you saw how the fi elds in a structure are initialized by using a constructor. However, because structures are value types, you can create structure variables without calling a constructor, as shown in the following example: Time now; In this example, the variable is created but its fi elds are left in their uninitialized state. Any attempt to access the values in these fi elds will result in a compiler error. The following graphic depicts the state of the fi elds in the now variable: If you call a constructor, the various rules of structure constructors described earlier guarantee that all the fi elds in the structure will be initialized: Time now = new Time(); 178 Part II Understanding the C# Language This time, the default constructor initializes the fi elds in the structure, as shown in the following graphic: Note that in both cases, the Time variable is created on the stack. If you’ve written your own structure constructor, you can also use that to initialize a structure variable. As explained earlier in this chapter, a structure constructor must always explicitly initialize all its fi elds. For example: struct Time { public Time(int hh, int mm) { hours = hh; minutes = mm; seconds = 0; } private int hours, minutes, seconds; } The following example initializes now by calling a user-defi ned constructor: Time now = new Time(12, 30); The following graphic shows the effect of this example: Chapter 9 Creating Value Types with Enumerations and Structs 179 Copying Structure Variables You’re allowed to initialize or assign one structure variable to another structure variable, but only if the structure variable on the right side is completely initialized (that is, if all its fi elds are initialized). The following example compiles because now is fully initialized. (The graphic shows the results of performing the assignment.) Time now = new Time(12, 30); Time copy = now; The following example fails to compile because now is not initialized: Time now; Time copy = now; // compile-time error: now has not been assigned When you copy a structure variable, each fi eld on the left side is set directly from the cor- responding fi eld on the right side. This copying is done as a fast, single operation that copies the contents of the entire structure and that never throws an exception. Compare this be- havior with the equivalent action if Time were a class, in which case both variables (now and copy) would end up referencing the same object on the heap. Note C++ programmers should note that this copy behavior cannot be customized. It’s time to put this knowledge into practice. In the following exercise, you will create and use a structure to represent a date. 180 Part II Understanding the C# Language Create and use a structure type 1. In the StructsAndEnums project, display the Date.cs fi le in the Code and Text Editor window. 2. Add a structure named Date inside the StructsAndEnums namespace. This structure should contain three private fi elds: one named year of type int, one named month of type Month (using the enumeration you created in the preceding exercise), and one named day of type int. The Date structure should look exactly as follows: struct Date { private int year; private Month month; private int day; } Consider the default constructor that the compiler will generate for Date. This con- structor will set the year to 0, the month to 0 (the value of January), and the day to 0. The year value 0 is not valid (there was no year 0), and the day value 0 is also not valid (each month starts on day 1). One way to fi x this problem is to translate the year and day values by implementing the Date structure so that when the year fi eld holds the value Y, this value represents the year Y + 1900 (you can pick a different century if you prefer), and when the day fi eld holds the value D, this value represents the day D + 1. The default constructor will then set the three fi elds to values that represent the date 1 January 1900. 3. Add a public constructor to the Date structure. This constructor should take three parameters: an int named ccyy for the year, a Month named mm for the month, and an int named dd for the day. Use these three parameters to initialize the corresponding fi elds. A year fi eld of Y represents the year Y + 1900, so you need to initialize the year fi eld to the value ccyy – 1900. A day fi eld of D represents the day D + 1, so you need to initialize the day fi eld to the value dd – 1. The Date structure should now look like this (the constructor is shown in bold): struct Date { public Date(int ccyy, Month mm, int dd) { this.year = ccyy - 1900; this.month = mm; this.day = dd - 1; } private int year; private Month month; private int day; } C reate an d use a structure type Chapter 9 Creating Value Types with Enumerations and Structs 181 4. Add a public method named ToString to the Date structure after the constructor. This method takes no arguments and returns a string representation of the date. Remember, the value of the year fi eld represents year + 1900, and the value of the day fi eld repre- sents day + 1. Note The ToString method is a little different from the methods you have seen so far. Every type, including structures and classes that you defi ne, automatically has a ToString method whether or not you want it. Its default behavior is to convert the data in a variable to a string representation of that data. Sometimes, the default behavior is meaningful; oth- er times, it is less so. For example, the default behavior of the ToString method generated for the Date class simply generates the string “StructsAndEnums.Date”. To quote Zaphod Beeblebrox in The Restaurant at the End of the Universe (Douglas Adams, Del Rey, 2005), this is “shrewd, but dull.” You need to defi ne a new version of this method that overrides the default behavior by using the override keyword. Overriding methods are discussed in more detail in Chapter 12. The ToString method should look like this: public override string ToString() { return this.month + “ “ + (this.day + 1) + “ “ + (this.year + 1900); } Note The + signs inside the parentheses are the arithmetic addition operator. The others are the string concatenation operator. Without the parentheses, all occurrences of the + sign would be treated as the string concatenation operator because the expression being evaluated is a string. It can be a little confusing when the same symbol in a single expres- sion denotes different operators! 5. Display the Program.cs fi le in the Code and Text Editor window. 6. Add a statement to the end of the Entrance method to declare a local variable named defaultDate, and initialize it to a Date value constructed by using the default Date con- structor. Add another statement to Entrance to write the defaultDate variable to the console by calling Console.WriteLine. Note The Console.WriteLine method automatically calls the ToString method of its argument to format the argument as a string. 182 Part II Understanding the C# Language The Entrance method should now look like this: static void Entrance() { Date defaultDate = new Date(); Console.WriteLine(defaultDate); } 7. On the Debug menu, click Start Without Debugging to build and run the program. Verify that the date January 1 1900 is written to the console. (The original output of the Entrance method will be displayed fi rst.) 8. Press the Enter key to return to the Visual Studio 2008 programming environment. 9. In the Code and Text Editor window, return to the Entrance method, and add two more statements. The fi rst statement should declare a local variable named halloween and initialize it to October 31 2008. The second statement should write the value of halloween to the console. The Entrance method should now look like this: static void Entrance() { Date halloween = new Date(2008, Month.October, 31); Console.WriteLine(halloween); } Note When you type the new keyword, IntelliSense will automatically detect that there are two constructors available for the Date type. 10. On the Debug menu, click Start Without Debugging. Confi rm that the date October 31 2008 is written to the console below the previous information. 11. Press Enter to close the program. You have successfully used the enum and struct keywords to declare your own value types and then used these types in code.  If you want to continue to the next chapter: Keep Visual Studio 2008 running, and turn to Chapter 10.  If you want to exit Visual Studio 2008 now: On the File menu, click Exit. If you see a Save dialog box, click Yes (if you are using Visual Studio 2008) or Save (if you are using Visual C# 2008 Express Edition) and save the project. Chapter 9 Creating Value Types with Enumerations and Structs 183 Chapter 9 Quick Reference To Do this Declare an enumeration Write the keyword enum, followed by the name of the type, followed by a pair of braces containing a comma-separated list of the enumeration literal names. For example: enum Season { Spring, Summer, Fall, Winter } Declare an enumeration variable Write the name of the enumeration on the left followed by the name of the variable, followed by a semicolon. For example: Season currentSeason; Assign an enumeration variable to a value Write the name of the enumeration literal in combination with the name of the enumeration to which it belongs. For example: currentSeason = Spring; // error currentSeason = Season.Spring; // correct Declare a structure type Write the keyword struct, followed by the name of the structure type, followed by the body of the structure (the constructors, methods, and fi elds). For example: struct Time { public Time(int hh, int mm, int ss) { } private int hours, minutes, seconds; } Declare a structure variable Write the name of the structure type, followed by the name of the variable, followed by a semicolon. For example: Time now; Initialize a structure variable to a value Initialize the variable to a structure value created by calling the struc- ture constructor. For example: Time lunch = new Time(12, 30, 0); [...]... Hand class The Pack class has a method named Accept that takes a single parameter of type PlayingCard You need to create a loop that goes through the cards in the hand and passes them back to the pack 3 Complete the ReturnCardsTo method as shown here in bold: public void ReturnCardsTo(Pack pack) { foreach (PlayingCard card in cards) { pack.Accept(card); } cards.Clear(); } Chapter 10 Using Arrays and Collections... and cannot grow or shrink A collection can dynamically resize itself as required An array can have more than one dimension A collection is linear Note The items in a collection can be other collections, enabling you to mimic a multidimensional array, although a collection containing other collections can be somewhat confusing to use Chapter 10 Using Arrays and Collections 201 Using Collection Classes... record which slots in the hand no longer contain a PlayingCard You will study the code and then write two methods: one to shuffle a pack of cards and one to return the cards in a hand to the pack Deal the cards 1 Start Microsoft Visual Studio 2008 if it is not already running 2 Open the Cards project, located in the \Microsoft Press \Visual CSharp Step by Step\ Chapter 10\Cards folder in your Documents... ArrayList of its contents 4 On the Debug menu, click Start Without Debugging 5 On the form, click Deal The shuffled cards are dealt to the four hands as before 6 Click Return to Pack The hands are cleared The cards are now back in the pack 7 Click Deal again The shuffled cards are once again dealt to the four hands 8 Close the form Note If you click the Deal button twice without clicking Return to Pack, you lose... a constructor that creates and adds the 52 playing cards to the ArrayList by using the Accept method defined by this class The methods in this class constitute the typical operations that you would perform on a pack of cards (Shuffle, Deal) 3 Display the PlayingCard.cs file in the Code and Text Editor window, and examine its contents Playing cards are represented by the PlayingCard class A playing card... on each class Note There are collection classes that don’t always use object as their element type and that can hold value types as well as references, but you need to know a bit more about C# before we can talk about them You will meet these collection classes in Chapter 18, “Introducing Generics.” 1 94 Part II Understanding the C# Language The ArrayList Collection Class ArrayList is a useful class... i < cards.Count; i++) { int cardToSwap = random.Next(cards.Count - 1); object temp = cards[i]; cards[i] = cards[cardToSwap]; cards[cardToSwap] = temp; } } 2 04 Part II Understanding the C# Language 9 On the Debug menu, click Start Without Debugging 10 On the form, click Deal This time the pack is shuffled before dealing, as shown here (Your screen will differ slightly each time, because the card order... to continue to the next chapter: Keep Visual Studio 2008 running, and turn to Chapter 11 If you want to exit Visual Studio 2008 now: On the File menu, click Exit If you see a Save dialog box, click Yes (if you are using Visual Studio 2008) or Save (if you are using Visual C# 2008 Express Edition) and save the project 206 Part II Understanding the C# Language Chapter 10 Quick Reference To Do this Declare... Close the form The final step is to add the code to return the cards to the pack so that they can be dealt again Return the cards to the pack 1 Display the Hand.cs file in the Code and Text Editor window The Hand class, which also contains an ArrayList named cards, represents the cards held by a player The idea is that at any one time, each card is either in the pack or in a hand 2 Locate the ReturnCardsTo... graphic: The element type of all the collection classes shown in this chapter is an object This means that when you insert a value into a collection, it is always boxed, and when you remove a value from a collection, you must unbox it by using a cast The following sections provide a very quick overview of four of the most useful collection classes Refer to the Microsoft NET Framework Class Library documentation . and Collections 193 The basic collection classes accept, hold, and return their elements as objects—that is, the element type of a collection class is an object. To understand the implications. to a structure value created by calling the struc- ture constructor. For example: Time lunch = new Time(12, 30, 0); 185 Chapter 10 Using Arrays and Collections After completing this chapter,. about C# before we can talk about them. You will meet these collection classes in Chapter 18, “Introducing Generics.” 1 94 Part II Understanding the C# Language The ArrayList Collection Class

Ngày đăng: 12/08/2014, 21:20

Từ khóa liên quan

Mục lục

  • Part II: Understanding the C# Language

    • Chapter 9: Creating Value Types with Enumerations and Structures

      • Working with Structures

        • Understanding Structure and Class Differences

        • Declaring Structure Variables

        • Understanding Structure Initialization

        • Copying Structure Variables

        • Chapter 9 Quick Reference

        • Chapter 10: Using Arrays and Collections

          • What Is an Array?

            • Declaring Array Variables

            • Creating an Array Instance

            • Initializing Array Variables

            • Creating an Implicitly Typed Array

            • Accessing an Individual Array Element

            • Iterating Through an Array

            • Copying Arrays

            • What Are Collection Classes?

              • The ArrayList Collection Class

              • The Queue Collection Class

              • The Stack Collection Class

              • The Hashtable Collection Class

              • The SortedList Collection Class

              • Using Collection Initializers

              • Comparing Arrays and Collections

              • Using Collection Classes to Play Cards

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan