We all know that the two data types of c # Are value type and reference type respectively. Many people may be able to tell with closed eyes that the value types include simple type, struct type, and enumeration type. The reference types include custom classes, arrays, interfaces, and delegation, however, when asked about the relationship and difference between the two, when struct is used and when class is used, it is often hard to understand. Therefore, it is necessary to understand the essential differences between the value type and the reference type.
- The value type directly stores its value, and the variable itself contains its instance data, while the reference type stores only the memory reference of the instance data. Therefore, a value type variable will never affect other value type variables, and the two referenced type variables may point to the same address, thus affecting each other.
- From the memory allocation perspective, the value type is usually allocated to the thread stack. When the scope ends, the occupied space is released independently, which is highly efficient and does not require address conversion, the reference type is usually distributed on the managed stack and controlled by GC, which requires address conversion and lower efficiency. This is one of the reasons c # needs to define two data types.
- Value types are implicitly derived from System. valueType, while System. valueType is directly derived from System. object, each value type has an implicit default constructor to initialize the default value of this type. Note that all value types are sealed, so a new value type cannot be derived. And System. valueType itself is a class type, not a value type. Because it overrides the Equals () method of the object, the value type is compared based on the Instance value instead of the reference address.
- C #'s unified type system enables value types to be converted to objects for processing. This is often referred to as packing and unpacking. Since it is necessary to create a new object or perform forced type conversion for unpacking, the time and operation required for these operations is far greater than the value assignment operation, so it is not recommended to use it, at the same time, try to avoid the occurrence of implicit unpacking.
Note: The stack is a continuous memory area allocated by the operating system for fast data access. Because the capacity of the value type is known, it can be stored on the stack. Managed heap is a continuous memory area reserved by CLR for the application at startup, and is used for dynamic memory allocation. The reference type of capacity can only be determined at runtime, all reference types are stored in heap.
One of the two data types of C # -- Memory Allocation of nested types
When the reference type is nested value type and the value type is nested, the memory allocation can be determined based on the following two rules:
• The reference type is always deployed on the managed stack;
• The value type is always assigned to the place it declares: as a field, it follows the object storage to which it belongs; as a local variable, it is stored on the stack.
The second extension of the two data types of C # -- string type
String is an interesting reference type. Why is it interesting? Because it represents the characteristics of many value types. Take a look at the sample code:
Example 1
String str1 = "abc ";
String str2 = str1;
Str1 = "123 ";
Console. WriteLine (str2 );
Example 2 (msdn example)
String a = "hello ";
String B = "h ";
// Append to contents of B
B + = "ello ";
Console. WriteLine (a = B );
The output result of Example 1 is abc. Changing the value of str1 has no effect on str2.
The output result of Example 2 is True.
This result may mistakenly assume that string is a value type. Otherwise, in Example 1, The str1 = "123" Statement compiler creates a new String object to save the New Character Sequence "123", that is, str1 is no longer another str1, the change of "this" str1 value cannot affect the value of "he" str1. Of course, the value of str2 will not change. In essence, str1 = "123" is short for str1 = new string ("123"). Every time it is assigned a value, the original object is discarded and A new string object is generated, allocate new memory space, so the string is unchangeable. To create modifiable strings, use stringbuilder for better performance. As for example 2, the string operator is redefined for the convenience of comparing string values.=And! =.
The third extension of the two data types of C # -- struct and class
The syntax of class and struct is basically the same, from declaration to use, they are very similar. However, struct has more constraints than class. In theory, struct can achieve the same class, but stuct that can be achieved by class is not necessarily customized, that is, struct can be replaced by class. Why?