C# step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型

C# 2012 step by step 学习笔记8 CHAPTER 9 使用枚举和结构创建值类型

本章内容

  1. 声明一个枚举类型
  2. 创建并使用一个枚举类型
  3. 声明一个结构类型
  4. 创建并使用一个结构类型
  5. 解释结构和类之间行为的区别

声明一个枚举

        enum Season { Spring, Summer, Fall, Winter }

使用枚举


        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 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 enumeration. By default, the numbering starts at 0 for the first element and goes up in steps of 1.
        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).
        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.
enum Season { Spring, Summer, Fall, Autumn = Fall, Winter }

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 example, 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).

Working with Structures

         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

        In C#, the primitive numeric types int, long, and float are aliases for the structures System.Int32, System.Int64, and System.Single, respectively. These structures have fields and methods, and you can actually call methods on variables and literals of these types. 

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.
原文地址:https://www.cnblogs.com/yjbjingcha/p/7346097.html