Structure, enumeration, boxing, unboxing custom value types use structs to define new value types and make them behave like most predefined types, where the key is that any newly defined value types have their own data and methods. An enumeration is typically used to define a collection of constant values. 1. Value types all value types derive from class System.ValueType. All classes are derived from class System.Object. Value types directly contain values. In other words, the location of a variable reference is where the value is actually stored in memory. Therefore, assigning the value of the first variable to a second variable creates a memory copy of the value of the original variable at the location of the new variable. So changing the value of the first variable does not affect the value of the second variable, because the value type uses a specific location in memory. The amount of memory required for a value type is fixed at compile time and does not change at run time. Because the size is fixed, all value types can be stored in a memory area called a stack. 2, reference type reference type is also a variable, the location of the variable reference as described above is where the value is actually stored in memory, stored in the stack (but the stored data is a memory address, size is the number of bytes of shaping data, rather than the actual data we store), The memory that is stored in this variable refers to the memory that is actually the actual data we store, and the actual data is in the heap. This memory address number points to a block of memory in the heap. At run time, the memory location is read from the variable, and then the memory that contains the actual data is found based on the memory address that is referred to the heap. So when assigning to another variable, the copy is a memory address number (which is the memory address of the actual data store, not the actual data, after an indirect jump). At run time, changing the data of this variable instead of its point (so-called change point is to re-point to a new address), will change the actual data. When used as a function parameter, if declared as ref or out, the unity of the value type and reference type replication is the memory number of the variable, so if it is a value type, you can change the data in the memory number (). It is also the actual data (the data of the argument). In the case of reference types, in addition to changing the actual data as above, you can also change the direction of incoming arguments and cancel the point to the original actual data (if the actual data points to only this one, the memory will be reclaimed for the next garbage collection). Note: The memory number is actually an integer data (integer type that can represent all memory address numbers) 32 bits, or 64 bits, which are determined by the number of bits of the processor.  1, structure (value type) Note: Although the language itself is not required, but as a good habit, you should ensure that the value type is immutable, in other words, once a value type is instantiated, that instance cannot be modified. If you need to modify it, you should create a new instance. In addition to attributes and fields, a struct can also contain methods and constructors, but it cannot contain a default (parameterless) constructor. Sometimes (for example, when instantiating an array) the constructor of a value type is not called because all array memory is converted to zero initialization. To avoid inconsistencies because the default constructor is only occasionally called, C # completely prohibits the user from explicitly defining the default constructor because the compiler puts the instance field assignment at the time of the declaration into the type's constructor, so C # is the equivalent of banning the assignment of an instance field at the time of declaration. C # supports constructors with parameters. And you need to initialize all the fields in the constructor, otherwise a compilation error will occur. Because it is a value type, there is no finalizer. Garbage collection is only for memory allocated in the heap. The default operator uses the default (data type), such as: Default (int) value types are sealed, and all value types derive from System.ValueType. This means that the inheritance chain problem of a struct is from object to valuetype to struct. Value types can also implement interfaces. As with classes, you can override System.Object's virtual members in a value type. One difference from a reference type override is that, for value types, the default implementation of GetHashCode () invokes the first non-empty field that is forwarded to a struct. In addition, Equals () uses a large number of reflection mechanisms. So, if a value type is used frequently in a collection, especially a collection of dictionary types that use code, the value type should contain both the override of Equals () and GetHashCode ().
1 structAngle2 {3 4 PublicAngle (intHoursintMinutesintseconds)5 {6_hours =hours;7_minutes =minutes;8_seconds =seconds;9 }Ten Public intHours One { A Get - { - return_hours; the } - } - Private int_hours; - Public intMinutes + { - Get + { A return_minutes; at } - } - Private int_minutes; - Public intSeconds - { - Get in { - return_seconds; to } + } - Private int_seconds; the PublicAngle Move (intHoursintMinutesintseconds) * { $ return NewAngle (Hours + Hours, Minutes + Minutes, Seconds +seconds);Panax Notoginseng } - } the + classcoordinate A { the PublicAngle Latitude + { - Get $ { $ return_longitude; - } - Set the { -_longitude =value;Wuyi } the } - PrivateAngle _longitude; Wu - PublicAngle Latitude About { $ Get - { - return_latitude; - } A Set + { the_latitude =value; - } $ } the PrivateAngle _latitude; the } the
2. Boxing because local variable value types (variables declared in functions) directly contain their data, and their interfaces and System.Object contain references to their data. It is therefore important to consider what happens when a value type is turned into an interface that it implements or its base class object. Such a transformation process is called boxing. When converting from a value type to a reference type, the following steps are involved.
Step One: First allocate the memory in the heap, it will be used to hold the value type of data and a little extra overhead (a syncblockindex and Method table pointers) Step two: Then a memory copy action occurs, the value type data on the stack to be allocated on the heap location. Step three: Finally, the object or interface references are updated to point to the location on the heap. The reverse process is called unpacking. By definition, CIL instruction unbox simply dereference (dereference) The data on the heap, and does not include actions copied from the heap to the stack. In the C # language, however, most of the time a copy action occurs immediately after unpacking. Boxing and unpacking can have some impact on performance and behavior. (You should read more CIL and count the number of Box/unbox instructions in a particular code snippet) requires additional learning: to learn. How to avoid boxing and unpacking 3, enumeration enumeration is a type that a developer can define. The key feature of an enumeration is that it identifies a collection of all possible values defined at compile time, each of which is referenced by a name. To reference an enumeration value, you need to append an enumeration name prefix to it.
1 enum Short 2 {3 disconnected,4 ,5 conntected,6 Joined = conntected,7 disconnecting8 }
The first enumeration value defaults to 0, and later automatically adds a 1 enumeration problem with an underlying type, which may be an int, uint, LOGN, ulong. But it cannot be a char. The default value type is int. However, you can use the inheritance syntax to specify a different type. The performance of an enumeration type depends entirely on the performance of the underlying type. Note: Transformations are allowed without the corresponding enumeration values, and the advantage is that enumerations can add new values to future API releases without destroying earlier versions. Enumerations are slightly different from other value types because the inheritance chain of enumerations is from System.ValueType to System.Enum to enum. Type compatibility between 3, 1 Enumerations C # does not support a direct transformation between two different enumeration arrays, but can be transformed by intermediate data types (arrays). The 3, 2 enumeration, and the conversion output enumeration identifier between the strings. The 3, 3 enumeration is used as a flag to assign values using a shift. or OR or OR and or using FlagsAttribute: [Flags] Before enumeration, this flag indicates that multiple enumeration values are used together. Enumerations and structs still require intensive learning.
Viii. C # Value types