C# 2012 step by step 學習筆記8 CHAPTER 9 Creating Value types with enumerations and Structures
things about
1. Declare an enumeration type.
2. Create and use an enumeration type.
3. Declare a structure type.
4. Create and use a structure type.
5. Explain the differences in behavior between a structure and a class.
Declaring an enumeration
enum Season { Spring, Summer, Fall, Winter }
Using an enumeration
You can assign a value that is defined by the enumeration only to an enumeration variable.
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;
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.
Many of the standard operators you can use on integer variables can also be used on enumeration variables (except the bitwise and shift Z喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcGVyYXRvcnMsIHdoaWNoIGFyZSBjb3ZlcmVkIGluIENoYXB0ZXIgMTYsIKGwVXNpbmcgSW5kZXhlcnOhsSkuIEZvciBleGFtcGxlLCB5b3UgY2FuIGNvbXBhcmUgdHdvIGVudW1lcmF0aW9uCiB2YXJpYWJsZXMgb2YgdGhlIHNhbWUgdHlwZSBmb3IgZXF1YWxpdHkgYnkgdXNpbmcgdGhlIGVxdWFsaXR5IG9wZXJhdG9yICg9PSksIGFuZCB5b3UgY2FuIGV2ZW4gcGVyZm9ybSBhcml0aG1ldGljIG9uIGFuIGVudW1lcmF0aW9uIHZhcmlhYmxlIChhbHRob3VnaCB0aGUgcmVzdWx0IG1pZ2h0IG5vdCBhbHdheXMgYmUgbWVhbmluZ2Z1bCEpLgo8aDM+Q2hvb3NpbmcgZW51bWVyYXRpb24gTGl0ZXJhbCBWYWx1ZXM8L2gzPgogICAgICAgIEludGVybmFsbHksIGFuIGVudW1lcmF0aW9uIHR5cGUgYXNzb2NpYXRlcyBhbiBpbnRlZ2VyIHZhbHVlIHdpdGggZWFjaCBlbGVtZW50IG9mIHRoZSBlbnVtZXJhdGlvbi4gQnkgZGVmYXVsdCwgdGhlIG51bWJlcmluZyBzdGFydHMgYXQgMCBmb3IgdGhlIGZpcnN0IGVsZW1lbnQgYW5kIGdvZXMgdXAgaW4gc3RlcHMgb2YgMS48YnI+CgogICAgICAgIElmIHlvdSBwcmVmZXIsIHlvdSBjYW4gYXNzb2NpYXRlIGEgc3BlY2lmaWMgaW50ZWdlciBjb25zdGFudCAoc3VjaCBhcyAxKSB3aXRoIGFuIGVudW1lcmF0aW9uIGxpdGVyYWwgKHN1Y2ggYXMgU3ByaW5nKSwgYXMgaW4gdGhlIGZvbGxvd2luZyBleGFtcGxlOiAKZW51bSBTZWFzb24geyBTcHJpbmcgPSAxLCBTdW1tZXIsIEZhbGwsIFdpbnRlciB9PGJyPgoKICAgICAgICBJbXBvcnRhbnSjulRoZSBpbnRlZ2VyIHZhbHVlIHdpdGggd2hpY2ggeW91IGluaXRpYWxpemUgYW4gZW51bWVyYXRpb24gbGl0ZXJhbCBtdXN0IGJlIGEgY29tcGlsZS10aW1lIGNvbnN0YW50IHZhbHVlIChzdWNoIGFzIDEpLjxicj4KCiAgICAgICAgdGhlIHVuZGVybHlpbmcgdmFsdWVzIG9mIFNwcmluZywgU3VtbWVyLCBGYWxsLCBhbmQgV2ludGVyIGFyZSBub3cgMSwgMiwgMywgYW5kIDQuPGJyPgoKICAgICAgICBZb3UgYXJlIGFsbG93ZWQgdG8gZ2l2ZSBtb3JlIHRoYW4gb25lIGVudW1lcmF0aW9uIGxpdGVyYWwgdGhlIHNhbWUgdW5kZXJseWluZyB2YWx1ZS48YnI+CgplbnVtIFNlYXNvbiB7IFNwcmluZywgU3VtbWVyLCBGYWxsLCBBdXR1bW4gPSBGYWxsLCBXaW50ZXIgfTxicj4KCjxoMz5DaG9vc2luZyBhbiBlbnVtZXJhdGlvbqGvcyBVbmRlcmx5aW5nIHR5cGU8L2gzPgogICAgICAgIFdoZW4geW91IGRlY2xhcmUgYW4gZW51bWVyYXRpb24sIHRoZSBlbnVtZXJhdGlvbiBsaXRlcmFscyBhcmUgZ2l2ZW4gdmFsdWVzIG9mIHR5cGUgaW50LiBZb3UgY2FuIGFsc28gY2hvb3NlIHRvIGJhc2UgeW91ciBlbnVtZXJhdGlvbiBvbiBhIGRpZmZlcmVudCB1bmRlcmx5aW5nIGludGVnZXIgdHlwZS4gRm9yIGV4YW1wbGUsIHRvIGRlY2xhcmUgdGhhdCBTZWFzb26hr3MgdW5kZXJseWluZyB0eXBlIGlzIGEgc2hvcnQgcmF0aGVyCiB0aGFuIGFuIGludCwgeW91IGNhbiB3cml0ZSB0aGlzOjxicj4KZW51bSBTZWFzb24gOiBzaG9ydCB7IFNwcmluZywgU3VtbWVyLCBGYWxsLCBXaW50ZXIgfTxicj4KICAgICAgICBUaGUgbWFpbiByZWFzb24gZm9yIGRvaW5nIHRoaXMgaXMgdG8gc2F2ZSBtZW1vcnk7IGFuIGludCBvY2N1cGllcyBtb3JlIG1lbW9yeSB0aGFuIGEgc2hvcnQsIGFuZCBpZiB5b3UgZG8gbm90IG5lZWQgdGhlIGVudGlyZSByYW5nZSBvZiB2YWx1ZXMgYXZhaWxhYmxlIHRvIGFuIGludCwgdXNpbmcgYSBzbWFsbGVyIGRhdGEgdHlwZSBjYW4gbWFrZSBzZW5zZS48YnI+CgogICAgICAgIFlvdSBjYW4gYmFzZSBhbiBlbnVtZXJhdGlvbiBvbiBhbnkgb2YgdGhlIGVpZ2h0IGludGVnZXIgdHlwZXM6IGJ5dGUsIHNieXRlLCBzaG9ydCwgdXNob3J0LCBpbnQsIHVpbnQsbG9uZywgb3IgdWxvbmcuIFRoZSB2YWx1ZXMgb2YgYWxsIHRoZSBlbnVtZXJhdGlvbiBsaXRlcmFscyBtdXN0IGZpdCBpbnNpZGUgdGhlIHJhbmdlIG9mIHRoZSBjaG9zZW4gYmFzZSB0eXBlLiBGb3IgZXhhbXBsZSwgaWYgeW91IGJhc2UgYW4gZW51bWVyYXRpb24KIG9uIHRoZSBieXRlIGRhdGEgdHlwZSwgeW91IGNhbiBoYXZlIGEgbWF4aW11bSBvZiAyNTYgbGl0ZXJhbHMgKHN0YXJ0aW5nIGF0IDApLjxicj4KCjxoMz5Xb3JraW5nIHdpdGggU3RydWN0dXJlczwvaDM+CiAgICAgICAgIEluIHNvbWUgY2FzZXMsIHRoZSBjbGFzcyBjYW4gY29udGFpbiBzbyBsaXR0bGUgZGF0YSB0aGF0IHRoZSBvdmVyaGVhZCBvZiBtYW5hZ2luZyB0aGUgaGVhcCBiZWNvbWVzIGRpc3Byb3BvcnRpb25hdGUuIEluIHRoZXNlIGNhc2VzLCBpdCBpcyBiZXR0ZXIgdG8gZGVmaW5lIHRoZSB0eXBlIGFzIGEgc3RydWN0dXJlLiBBIHN0cnVjdHVyZSBpcyBhIHZhbHVlIHR5cGUuIEJlY2F1c2Ugc3RydWN0dXJlcyBhcmUgc3RvcmVkIG9uCiB0aGUgc3RhY2ssIGFzIGxvbmcgYXMgdGhlIHN0cnVjdHVyZSBpcyByZWFzb25hYmx5IHNtYWxsLCB0aGUgbWVtb3J5IG1hbmFnZW1lbnQgb3ZlcmhlYWQgaXMgb2Z0ZW4gcmVkdWNlZC48YnI+CgogICAgICAgIExpa2UgYSBjbGFzcywgYSBzdHJ1Y3R1cmUgY2FuIGhhdmUgaXRzIG93biBmaWVsZHMsIG1ldGhvZHMsIGFuZCAod2l0aCBvbmUgaW1wb3J0YW50IGV4Y2VwdGlvbiBkaXNjdXNzZWQgbGF0ZXIgaW4gdGhpcyBjaGFwdGVyKSBjb25zdHJ1Y3RvcnMuPGJyPgoKPGg0PkNvbW1vbiBTdHJ1Y3R1cmUgdHlwZXM8L2g0PgogICAgICAgIEluIEMjLCB0aGUgcHJpbWl0aXZlIG51bWVyaWMgdHlwZXMgaW50LCBsb25nLCBhbmQgZmxvYXQgYXJlIGFsaWFzZXMgZm9yIHRoZSBzdHJ1Y3R1cmVzIFN5c3RlbS5JbnQzMiwgU3lzdGVtLkludDY0LCBhbmQgU3lzdGVtLlNpbmdsZSwgcmVzcGVjdGl2ZWx5LiBUaGVzZSBzdHJ1Y3R1cmVzIGhhdmUgZmllbGRzIGFuZCBtZXRob2RzLCBhbmQgeW91IGNhbiBhY3R1YWxseSBjYWxsIG1ldGhvZHMgb24gdmFyaWFibGVzIGFuZCBsaXRlcmFscwogb2YgdGhlc2UgdHlwZXMuIDxicj4KCjxpbWcgc3JjPQ=="http://www.2cto.com/uploadfile/Collfiles/20140612/20140612092055394.png" alt="\">
Declaring a Structure
To declare your own structure type, you use the struct keyword followed by the name of the type, followed by the body of the structure between opening and closing braces. Syntactically, the process is similar to declaring a class.
As with classes, making the fields of a structure public is not advisable in most cases; there is no way to control the values held in public fields.A better idea is to make the fields private and provide your structure with constructors and methods
to initialize and manipulate these fields。
Note By default, you cannot use many of the common operators on your own structure types. For example, you cannot use operators such as the equality operator (==) and the inequality operator (!=) on your own structure type variables. However, you
can use the builtin Equals() method exposed by all structures to compare them, and you can also explicitly declare and implement operators for your own structure types. The syntax for doing this is covered in Chapter 22, “Operator Overloading.”
tip Use structures to implement simple concepts whose main feature is their value rather than the functionality that they provide.
Understanding Structure and Class Differences
You can’t declare a default constructor (a constructor with no parameters) for a structure.
The reason you can’t declare your own default constructor for a structure is that the compiler always generates one.
You can initialize fields to different values by providing a nondefault constructor. However,when you do this, your nondefault constructor must explicitly initialize all fields in your structure; the default initialization no longer occurs. If
you fail to do this, you’ll get a compile-time error.
In a class, you can initialize instance fields at their point of declaration. In a structure, you cannot.
There are other differences between classes and structures concerning inheritance. These differences are covered in Chapter 12, “Working with Inheritance.”
Declaring Structure Variables
Note As with enumerations, you can create a nullable version of a structure variable by using the ? modifier. You can then assign the null value to the variable:
Time? currentTime = null;
Understanding Structure Initialization
Time now = new Time();
However, because structures are value types, you can also create structure variables without calling a constructor
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.
Time now = new Time(12, 30);
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 fields are populated with valid data rather than undefined
values).
Date now = new Date();
Date copy = now;
When you copy a structure variable, each field on the left side is set directly from the corresponding field 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.
Note C++ programmers should note that this copy behavior cannot be customized.
Structs and Compatibility with the Windows runtime on Windows 8
All C# applications execute by using the common language runtime (CLR) of the .NET Framework. The CLR is responsible for providing a safe and secure environment for your application code in the form of a virtual machine。When you compile a C# application,
the compiler converts your C# code into a set of instructions using a pseudo-machine code called the Common Intermediate Language (CIL).These are the instructions that are stored in an assembly. When you run a C#
application, the CLR takes responsibility for converting the CIL instructions into real machine instructions that the processor on your computer can understand and execute. This whole environment is known as the managed execution environment, and C# programs
are frequentlyreferred to as managed code.
On Windows 7 and earlier, you can additionally write unmanaged applications, also known as native code, based on the Win32 APIs, which are the APIs that interface directly with the Windows operating system (the CLR also converts many of the functions
in the .NET Framework into Win32 API calls if you are running a managed application, although this process is totally transparent to your code). To do this, you can use a language such as C++. The .NET Framework enables you to integrate managed code into unmanaged
applications and vice versa through a set of interoperability technologies.
Windows 8 implements an alternative strategy, in the form of the Windows Runtime, or WinRT. WinRT provides a layer on top of the Win32 API (and other selected native Windows APIs) that is optimized for touch-based devices and user interfaces, such
as those found on Windows 8 tablets. When you build a native application on Windows 8, you use the APIs exposed by WinRT rather than Win32. Similarly, the CLR on Windows 8 also uses WinRT; all managed code written by using C# or any other managed language
is still executed by the CLR, but at run time the CLR converts your code into WinRT API calls rather than Win32. Between them, the CLR and WinRT are responsible for managing and running your code safely.
A primary purpose of WinRT is to simplify the interoperability between languages, enabling you to more easily integrate components developed by using different programming languages into a single seamless application. However, this simplicity comes
at a cost, and you have to be prepared to make a few compromises based on the different feature sets of the various languages available. In particular, for historical reasons, although C++ supports structures, it does not recognize member functions. In C#
terms, a member function is an instance method. So, if you are building C# structs that you want to package up in a library to make available to developers programming in C++ (or any other unmanaged language), these structs should not contain any instance
methods. The same restriction applies to static methods in
structs. If you want to include instance or static methods, you should convert your struct into a class. Additionally, structs cannot contain private fields, and all public fields must be C# primitive types, conforming value types, or strings.
WinRT also imposes some other restrictions on C# classes and structs if you want to make them available to native applications. Chapter 13, “Creating Interfaces and Defining Abstract Classes” provides more information.