Microsoft Visual C# 2010 Step by Step (P5) potx

50 431 1
Microsoft Visual C# 2010 Step by Step (P5) potx

Đ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

170 Part II Understanding the C# Language You can access and modify the value held in the variable i through the pointer variable pi like this: *pi = 100; This code updates the value of the variable i to 100 because pi points to the same memory location as the variable i. One of the main problems that developers learning C and C++ have is understanding the syntax used by pointers. The * operator has at least two meanings (in addition to being the arithmetic multiplication operator), and there is often great confusion about when to use & rather than *. The other issue with pointers is that it is easy to point somewhere invalid, or to forget to point somewhere at all, and then try to reference the data pointed to. The result will be either garbage or a program that fails with an error because the operating system detects an attempt to access an illegal address in memory. There is also a whole range of security flaws in many existing systems result- ing from the mismanagement of pointers; some environments (not Microsoft Windows) fail to enforce checks that a pointer does not refer to memory that belongs to another process, opening up the possibility that confidential data could be compromised. Reference variables were added to C# to avoid all these problems. If you really want to, you can continue to use pointers in C#, but you must mark the code as unsafe. The un- safe keyword can be used to mark a block of code, or an entire method, as shown here: public static void Main(string [] args) { int x = 99, y = 100; unsafe { swap (&x, &y); } Console.WriteLine("x is now {0}, y is now {1}", x, y); } public static unsafe void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } When you compile programs containing unsafe code, you must specify the /unsafe option. Unsafe code also has a bearing on how memory is managed; objects created in unsafe code are said to be unmanaged. We discuss this issue in more detail in Chapter 14. Chapter 8 Understanding Values and References 171 In this chapter, you learned about some important differences between value types that hold their value directly on the stack and reference types that refer indirectly to their objects on the heap. You also learned how to use the ref and out keywords on method parameters to gain access to the arguments. You saw how assigning a value (such as the int 42) to a variable of the System.Object class creates a boxed copy of the value on the heap and then causes the System.Object variable to refer to this boxed copy. You also saw how assigning a variable of a value type (such as an int) to a variable of the System.Object class copies (or unboxes) the value in the System.Object class to the memory used by the int. n If you want to continue to the next chapter Keep Visual Studio 2010 running, and turn to Chapter 9. n If you want to exit Visual Studio 2010 now On the File menu, click Exit. If you see a Save dialog box, click Yes and save the project. Chapter 8 Quick Reference To Do this Copy a value type variable Simply make the copy. Because the variable is a value type, you will have two copies of the same value. For example: int i = 42; int copyi = i; Copy a reference type variable Simply make the copy. Because the variable is a reference type, you will have two references to the same object. For example: Circle c = new Circle(42); Circle refc = c; Declare a variable that can hold a value type or the null value Declare the variable using the ? modifier with the type. For example: int? i = null; Pass an argument to a ref parameter Prefix the argument with the ref keyword. This makes the parameter an alias for the actual argument rather than a copy of the argument. The method may change the value of the parameter, and this change is made to the actual argument rather than a local copy. For example: static void Main() { int arg = 42; DoWork(ref arg); Console.WriteLine(arg); } 172 Part II Understanding the C# Language To Do this Pass an argument to an out parameter Prefix the argument with the out keyword. This makes the parameter an alias for the actual argument rather than a copy of the argument. The method must assign a value to the parameter, and this value is made to the actual argument. For example: static void Main() { int arg = 42; DoWork(out arg); Console.WriteLine(arg); } Box a value Initialize or assign a variable of type object to the value. For example: object o = 42; Unbox a value Cast the object reference that refers to the boxed value to the type of the value variable. For example: int i = (int)o; Cast an object safely Use the is operator to test whether the cast is valid. For example: WrappedInt wi = new WrappedInt(); object o = wi; if (o is WrappedInt) { WrappedInt temp = (WrappedInt)o; } Alternatively, use the as operator to perform the cast, and test whether the result is null. For example: WrappedInt wi = new WrappedInt(); object o = wi; WrappedInt temp = o as WrappedInt; if (temp != null) 173 Chapter 9 Creating Value Types with Enumerations and Structures After completing this chapter, you will be able to: n Declare an enumeration type. n Create and use an enumeration type. n Declare a structure type. n Create and use a structure type. n Explain the differences in behavior between a structure and a class. In Chapter 8, “Understanding Values and References,” you learned about the two fundamental types that exist in Microsoft Visual C#: value types and reference types. A value type variable holds its value directly on the stack, whereas a reference type variable holds a reference to an object on the heap. In Chapter 7, “Creating and Managing Classes and Objects,” you learned how to create your own reference types by defining classes. In this chapter, you’ll learn how to create your own value types. C# supports two kinds of value types: enumerations and structures. We’ll look at each of them in turn. Working with Enumerations Suppose you want to represent the seasons of the year in a program. You could use the integers 0, 1, 2, and 3 to represent spring, summer, fall, and winter, respectively. This system would work, but it’s not very intuitive. If you used the integer value 0 in code, it wouldn’t be obvious that a particular 0 represented spring. It also wouldn’t be a very robust solution. For example, if you declare an int variable named season, there is nothing to stop you from as- signing it any legal integer value apart from 0, 1, 2, or 3. C# offers a better solution. You can create an enumeration (sometimes called an enum type), whose values are limited to a set of symbolic names. Declaring an Enumeration You define an enumeration by using the enum keyword, followed by a set of symbols identifying the legal values that the type can have, enclosed between braces. Here’s how to 174 Part II Understanding the C# Language declare an enumeration named Season whose literal values are limited to the symbolic names Spring, Summer, Fall, and Winter: enum Season { Spring, Summer, Fall, Winter } Using an Enumeration After you have declared an enumeration, you can use it in exactly the same way as any other type. If the name of your enumeration is Season, you can create variables of type Season, fields of type Season, and parameters of type Season, as shown in this example: enum Season { Spring, Summer, Fall, Winter } class Example { public void Method(Season parameter) { Season localVariable; } private Season currentSeason; } Before you can read the value of an enumeration variable, it must be assigned a value. You can assign a value that is defined by the enumeration only to an enumeration variable. For example: Season colorful = Season.Fall; Console.WriteLine(colorful); // writes out 'Fall' Note As you can with all value types, you can create a nullable version of an enumeration variable by using the ? modifier. You can then assign the null value, as well the values defined by the enumeration, to the variable: Season? colorful = null; Notice that you have to write Season.Fall rather than just Fall. All enumeration literal names are scoped by their enumeration type. This is useful because it allows different enumerations to coincidentally contain literals with the same name. Also, notice that when you display an enumeration variable by using Console.WriteLine, the compiler generates code that writes out the name of the literal whose value matches the value of the variable. If needed, you can explicitly convert an enumeration variable to a string Chapter 9 Creating Value Types with Enumerations and Structures 175 that represents its current value by using the built-in ToString method that all enumerations automatically contain. For example: string name = colorful.ToString(); Console.WriteLine(name); // also writes out 'Fall' Many of the standard operators you can use on integer variables can also be used on enu- meration variables (except the bitwise and shift operators, which are covered in Chapter 16, “Using Indexers”). For example, you can compare two enumeration variables of the same type for equality by using the equality operator (==), and you can even perform arithmetic on an enumeration variable (although the result might not always be meaningful!). Choosing Enumeration Literal Values Internally, an enumeration type associates an integer value with each element of the enumer- ation. By default, the numbering starts at 0 for the first element and goes up in steps of 1. It’s possible to retrieve the underlying integer value of an enumeration variable. To do this, you must cast it to its underlying type. Remember from the discussion of unboxing in Chapter 8 that casting a type converts the data from one type to another as long as the conversion is valid and meaningful. The following code example writes out the value 2 and not the word Fall (in the Season enumeration Spring is 0, Summer 1, Fall 2, and Winter 3): enum Season { Spring, Summer, Fall, Winter } Season colorful = Season.Fall; Console.WriteLine((int)colorful); // writes out '2' If you prefer, you can associate a specific integer constant (such as 1) with an enumeration literal (such as Spring), as in the following example: enum Season { Spring = 1, Summer, Fall, Winter } Important The integer value with which you initialize an enumeration literal must be a compile-time constant value (such as 1). If you don’t explicitly give an enumeration literal a constant integer value, the compiler gives it a value that is 1 greater than the value of the previous enumeration literal except for the very first enumeration literal, to which the compiler gives the default value 0. In the preced- ing example, the underlying values of Spring, Summer, Fall, and Winter are now 1, 2, 3, and 4. You are allowed to give more than one enumeration literal the same underlying value. For example, in the United Kingdom, Fall is referred to as Autumn. You can cater to both cultures as follows: enum Season { Spring, Summer, Fall, Autumn = Fall, Winter } 176 Part II Understanding the C# Language Choosing an Enumeration’s Underlying Type When you declare an enumeration, the enumeration literals are given values of type int. You can also choose to base your enumeration on a different underlying integer type. For exam- ple, to declare that Season’s underlying type is a short rather than an int, you can write this: enum Season : short { Spring, Summer, Fall, Winter } The main reason for doing this is to save memory; an int occupies more memory than a short, and if you do not need the entire range of values available to an int, using a smaller data type can make sense. You can base an enumeration on any of the eight integer types: byte, sbyte, short, ushort, int, uint, long, or ulong. The values of all the enumeration literals must fit inside the range of the chosen base type. For example, if you base an enumeration on the byte data type, you can have a maximum of 256 literals (starting at 0). Now that you know how to declare an enumeration, the next step is to use it. In the follow- ing exercise, you will work with a Console application to declare and use an enumeration that represents the months of the year. Create and use an enumeration 1. Start Microsoft Visual Studio 2010 if it is not already running. 2. Open the StructsAndEnums project, located in the \Microsoft Press\Visual CSharp Step By Step\Chapter 9\StructsAndEnums folder in your Documents folder. 3. In the Code and Text Editor window, display the Month.cs file. The source file contains an empty namespace named StructsAndEnums. 4. Add an enumeration named Month for modeling the months of the year inside the StructsAndEnums namespace, as shown in bold here. The 12 enumeration literals for Month are January through December. namespace StructsAndEnums { enum Month { January, February, March, April, May, June, July, August, September, October, November, December } } Chapter 9 Creating Value Types with Enumerations and Structures 177 5. Display the Program.cs file in the Code and Text Editor window. As in the exercises in previous chapters, the Main method calls the DoWork method and traps any exceptions that occur. 6. In the Code and Text Editor window, add a statement to the DoWork method to declare a variable named first of type Month and initialize it to Month.January. Add another statement to write the value of the first variable to the Console. The DoWork method should look like this: static void DoWork() { Month first = Month.January; Console.WriteLine(first); } Note When you type the period following Month, Microsoft IntelliSense will automatically display all the values in the Month enumeration. 7. On the Debug menu, click Start Without Debugging. Visual Studio 2010 builds and runs the program. Confirm that the word January is written to the console. 8. Press Enter to close the program and return to the Visual Studio 2010 programming environment. 9. Add two more statements to the DoWork method to increment the first variable and display its new value to the console, as shown in bold here: static void DoWork() { Month first = Month.January; Console.WriteLine(first); first++; Console.WriteLine(first); } 10. On the Debug menu, click Start Without Debugging. Visual Studio 2010 builds and runs the program. Confirm that the words January and February are written to the console. Notice that performing a mathematical operation (such as the increment operation) on an enumeration variable changes the internal integer value of the variable. When the variable is written to the console, the corresponding enumeration value is displayed. 178 Part II Understanding the C# Language 11. Press Enter to close the program and return to the Visual Studio 2010 programming environment. 12. Modify the first statement in the DoWork method to initialize the first variable to Month.December, as shown in bold here: static void DoWork() { Month first = Month.December; Console.WriteLine(first); first++; Console.WriteLine(first); } 13. On the Debug menu, click Start Without Debugging. Visual Studio 2010 builds and runs the program. This time the word December is written to the console, followed by the number 12. Although you can perform arithmetic on an enumeration, if the results of the operation are outside the range of values defined for the enumerator, all the runtime can do is interpret the value of the variable as the cor- responding integer value. 14. Press Enter to close the program and return to the Visual Studio 2010 programming environment. Working with Structures You saw in Chapter 8 that classes define reference types that are always created on the heap. In some cases, the class can contain so little data that the overhead of managing the heap becomes disproportionate. In these cases, it is better to define the type as a structure. A structure is a value type. Because structures are stored on the stack, as long as the structure is reasonably small, the memory management overhead is often reduced. Like a class, a structure can have its own fields, methods, and (with one important exception discussed later in this chapter) constructors. Common Structure Types You might not have realized it, but you have already used structures in previous exer- cises in this book. In C#, the primitive numeric types int, long, and float are aliases for the structures System.Int32, System.Int64, and System.Single, respectively. These struc- tures have fields and methods, and you can actually call methods on variables and liter- als of these types. For example, all of these structures provide a ToString method that Chapter 9 Creating Value Types with Enumerations and Structures 179 can convert a numeric value to its string representation. The following statements are all legal statements in C#: int i = 99; Console.WriteLine(i.ToString()); Console.WriteLine(55.ToString()); float f = 98.765F; Console.WriteLine(f.ToString()); Console.WriteLine(98.765F.ToString()); You don’t see this use of the ToString method often, because the Console.WriteLine method calls it automatically when it is needed. Use of the static methods exposed by these structures is much more common. For example, in earlier chapters you used the static int.Parse method to convert a string to its corresponding integer value. What you are actually doing is invoking the Parse method of the Int32 structure: string s = "42"; int i = int.Parse(s); // exactly the same as Int32.Parse These structures also include some useful static fields. For example, Int32.MaxValue is the maximum value that an int can hold, and Int32.MinValue is the smallest value you can store in an int. The following table shows the primitive types in C# and their equivalent types in the Microsoft .NET Framework. Notice that the string and object types are classes (refer- ence types) rather than structures. Keyword Type equivalent Class or structure bool System.Boolean Structure byte System.Byte Structure decimal System.Decimal Structure double System.Double Structure float System.Single Structure int System.Int32 Structure long System.Int64 Structure object System.Object Class sbyte System.SByte Structure short System.Int16 Structure string System.String Class uint System.UInt32 Structure ulong System.UInt64 Structure ushort System.UInt16 Structure [...]... (52-card) pack of playing cards You will complete the code that deals the cards for each hand Use arrays to implement a card game 1 Start Microsoft Visual Studio 2010 if it is not already running 2 Open the Cards project, located in the \Microsoft Press \Visual CSharp Step By Step\ Chapter 10\Cards Using Arrays folder in your Documents folder 3 On the Debug menu, click Start Without Debugging to build and... Understanding the C# Language n If you want to continue to the next chapter Keep Visual Studio 2010 running, and turn to Chapter 10 n If you want to exit Visual Studio 2010 now On the File menu, click Exit If you see a Save dialog box, click Yes and save the project 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... messages: July 4 2010 Value of copy is July 4 2010 New value of weddingAnniversary is July 4 2010 Value of copy is August 4 2010 The first message displays the initial value of the weddingAnniversary variable (July 4 2010) The second message displays the value of the weddingAnniversaryCopy variable You can see that it contains a copy of the date held in the weddingAnniversary variable (July 4 2010) The third... variable after changing the month of the weddingAnniversaryCopy variable to August 4 2010 Notice that it has not changed from its original value of July 4 2010 The final message displays the value of the weddingAnniversaryCopy variable You can see that this has changed to August 4 2010 8 Press Enter and return to Visual Studio 2010 9 Display the Date.cs file in the Code and Text Editor window 10 Change... Declaring Array Variables You declare an array variable by specifying the name of the element type, followed by a pair of square brackets, followed by the variable name The square brackets signify that the variable is an array For example, to declare an array of int variables named pins, you write int[] pins; // Personal Identification Numbers Microsoft Visual Basic programmers should note that you use square... console window displays the following messages: July 4 2010 Value of copy is July 4 2010 New value of weddingAnniversary is August 4 2010 Value of copy is August 4 2010 The first two messages and the fourth message are the same as before However, the third message shows that the value of the weddingAnniversary variable has changed to August 4 2010 Remember that a structure is a value type, and when... instance by using new Arrays follow the same rules—when you declare an array variable, you do not declare its size You specify the size of an array only when you actually create an array instance To create an array instance, you use the new keyword followed by the element type, followed by the size of the array you’re creating between square brackets Creating an array also initializes its elements by using... 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... struct, followed by the name of the structure type, followed by the body of the structure (the constructors, methods, and fields) 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... problems posed by these questions What Is an Array? An array is an unordered sequence of elements All the elements in an array have the same type (unlike the fields in a structure or class, which can have different types) The elements of an array live in a contiguous block of memory and are accessed by using an integer index (unlike fields in a structure or class, which are accessed by name) Declaring . enumeration 1. Start Microsoft Visual Studio 2010 if it is not already running. 2. Open the StructsAndEnums project, located in the Microsoft Press Visual CSharp Step By Step Chapter 9StructsAndEnums. to the memory used by the int. n If you want to continue to the next chapter Keep Visual Studio 2010 running, and turn to Chapter 9. n If you want to exit Visual Studio 2010 now On the File. displays the following messages: July 4 2010 Value of copy is July 4 2010 New value of weddingAnniversary is July 4 2010 Value of copy is August 4 2010 The first message displays the initial

Ngày đăng: 05/07/2014, 16:20

Từ khóa liên quan

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

Tài liệu liên quan