The meaning of packing and unpacking: The value type is the data container, which is stored on the stack and does not have polymorphism.. NET Framework in the design of the entire object level, the system. object is the base class of all types, but obejct is the reference type, and the base class of value type is system. valuetype, which is from system. objects are derived, which leads to a conflict. packing and unpacking are to solve the difference between the two types.
A value type is put into a reference object of an untyped type, so that the value type can be applied to those scenarios where only the reference type can be used. A copy of the value type is extracted from the preceding packing object. Both packing and unpacking are time-consuming operations.
The packing operation converts the value type to a reference type. In this process, a new reference exclusive is created and allocated to the stack, A copy of the value type is stored in the reference object. When we need to obtain any information from the packing object, a copy of the value type will be created, and then it will be returned. The key is:When we need to reference a type, a new object of the reference type will be created and put into the heap; when we need to access the information of the packed object, A copy of the corresponding value type is created and returned.
The biggest problem with packing and unpacking is that they happen automatically. When we use the value type and expect the reference type, the compiler will automatically generate the packing and unpacking statements.
Let's take a look at the following statement, and the packing and unpacking operations have also taken place.
Console.WriteLine("A few numbers:{0}, {1}, {2}",
25, 32, 50);
The preceding code is boxed because the parameter type required by the writeline method is system. object, while 25 is an int type and belongs to the value type. Therefore, it needs to be boxed. In the internal implementation of the writeline method, you need to call the tostring () method of the method parameter, in order to call the method of packing objects, the unpacking operation will occur.
To avoid packing and unpacking, you can modify the above Code as follows.
Console.WriteLine("A few numbers:{0}, {1}, {2}",
25.ToString(), 32.ToString(), 50.ToString());
In addition, because both packing and unpacking generate new instances, sometimes some strange bugs may occur. Let's look at the following code.
Code
1 public struct Person
2 {
3 private string _Name;
4
5 public string Name
6 {
7 get
8 {
9 return _Name;
10 }
11 set
12 {
13 _Name = value;
14 }
15 }
16
17 public override string ToString( )
18 {
19 Return _Name;
20 }
21 }
22
23 // Using the Person in a collection:
24 ArrayList attendees = new ArrayList( );
25 Person p = new Person( "Old Name" );
26 attendees.Add( p );
27
28 // Try to change the name:
29 // Would work if Person was a reference type.
30 Person p2 = (( Person )attendees[ 0 ] );
31 p2.Name = "New Name";
32
33 // Writes "Old Name":
34 Console.WriteLine(
35 attendees[ 0 ].ToString( ));
In the above Code, person is a value type. When it is put into arraylist, it will be boxed. At this time, there will be a copy operation. When we need to obtain information about the person object in arraylist, A case is split and a copy operation is performed again. Therefore, when the objects in the arraylist are not modified, the replicas are modified.
We can modify the problems in the above Code in the following ways.
Code
1 public interface IPersonName
2 {
3 string Name
4 {
5 get; set;
6 }
7 }
8
9 struct Person : IPersonName
10 {
11 private string _Name;
12
13 public string Name
14 {
15 get
16 {
17 return _Name;
18 }
19 set
20 {
21 _Name = value;
22 }
23 }
24
25 public override string ToString( )
26 {
27 return _Name;
28 }
29 }
30
31 // Using the Person in a collection:
32 ArrayList attendees = new ArrayList( );
33 Person p = new Person( "Old Name" );
34 attendees.Add( p ); // box
35
36 // Try to change the name:
37 // Use the interface, not the type.
38 // No Unbox needed
39 (( IPersonName )attendees[ 0 ] ).Name = "New Name";
40
41 // Writes "New Name":
42 Console.WriteLine(
43 attendees[ 0 ].ToString( )); // unbox
44
45
The reference type after packing implements all interfaces on the original value type object, which means no replication will happen again, but when we call ipersonname. when the name attribute is used, it will forward the call request to the value type inside the "box", and implement the interface on the value type so that we can access the inside of the "box, this allows you to directly change the information in the arraylist.
In short, we should convert any value type to system. object or interface type construction keeps a close eye on, for example, placing the value type into the set, and calling system on the value type. object-defined methods. All these operations convert the value type to system. object. We should avoid this conversion whenever possible.