, boxing and unpacking is an abstract concept 2, boxing is theValue types are converted toobject type is converted to each other, and the value type is linked to the reference type for example: int val =, Object obj = val; Console.WriteLine ("Value of object = {0}", obj); This is a boxing process, which is to convert the int val = +; Object obj = val; int num = (int) obj; Console.WriteLine ("Num: {0}", num); This is a process of unpacking, converting a value type to a reference type, and then converting from a reference type to a value type
Note: Objects that have been loaded can be removed from the box 3, . NET, the data type is divided into reference (not equivalent to C + + pointers)
4: What is packing/unpacking? Boxing: Used to store value types in the garbage collection heap. Boxing is an implicit conversion of a value type to an object type or to any interface type implemented by this value type. Unboxing: an explicit conversion from an object type to a value type or from an interface type to a value type that implements the interface.
5: Why do I need to pack? (Why do you want to convert a value type to a reference type?) one of the most common scenarios is to invoke a method with a parameter of type object that can support any type for general purpose. Boxing is required when you need to pass in a value type (such as Int32). Another usage is that a non-generic container is also defined as an object in order to guarantee common use. Therefore, boxing is required to add value type data to the container.
6: Internal operation of packing/unpacking. Boxing: Assigns an object instance to a value type in the heap and copies the value to the new object. Proceed as three steps. The first step: Allocate managed heap memory (size is the value type instance size plus a method table pointer and a syncblockindex). Step Two: Copy the instance field of the value type to the newly allocated memory. Step three: Returns the address of the newly allocated object in the managed heap. This address is a reference to an object. Some people understand this: if the Int32 is boxed, the returned address is pointing to a Int32. I don't think it's possible to understand this, but it does have a problem, as it is not comprehensive, and pointing to Int32 does not say its substance (in the managed heap). Unpacking: Checks the object instance to ensure that it is a boxed value of the given value type. Copy the value from the instance to the value type variable. In the book, unpacking just gets a pointer to the part of the value type in the Reference object, and the content copy is the trigger of the assignment statement. I don't think it matters. The key is to check the nature of the object instance, unpacking and boxing type must match, this point, on the IL layer, do not see the principle, my guess, perhaps called a similar gettype and other methods to remove the type to match (because of the need for strict matching).
7: The effect of boxing/unpacking on execution efficiency Obviously, it can be seen from the principle that when boxing occurs, a new reference object is generated, which can lead to loss of time, which results in less efficiency. So how do we do that? First, you should try to avoid boxing. For example, the two cases of Example 2, can be avoided, in the first case, can be avoided by overloading the function. In the second case, it can be avoided by generics. Of course, everything is not absolute, assuming you want to modify the code for a third-party assembly, you cannot change, then you can only be boxed. For the optimization of packing/unpacking code, because C # is implicit in boxing and unboxing, the fundamental approach is to analyze the code, and the most straightforward way to analyze it is to understand the principle of how to view the anti-compilation Il code. For example, there may be excess boxing in the body of the loop, and you can simply use the pre-packing method to optimize it.
8: A closer look at boxing/unpacking boxing/unpacking is not as straightforward as it says, such as: when boxing, it becomes a reference object, there will be more than one method table pointer, what is the use of it? We can use the example to further explore. Let me give you an example. Struct a:icloneable {public Int32 x; public override String ToString () {return String.Format ("{0}", x);} public Object Clone () {return MemberwiseClone ();}} static void Main () {a A; a.x = 100; Console.WriteLine (A.tostring ()); Console.WriteLine (A.gettype ()); A a2 = (a) a.clone (); ICloneable C = A2; Ojbect o = C.clone (); } 5.0:a. ToString (). The compiler finds that a overrides the ToString method and calls the ToString Directive directly. Because A is a value type, the compiler does not show polymorphic behavior. Therefore, it is called directly, not boxed. (Note: ToString is the base class of a System.ValueType method) 5.1:a. GetType (), GetType is a method inherited from System.ValueType, to invoke it, a method table pointer is required, and a is boxed to generate a method table pointer that invokes the System.ValueType of the base class. (in other words, all value types are inherited from System.ValueType). 5.2:a. Clone (), because a implements the Clone method, so no boxing is required. 5.3:icloneable Transformation: When A2 is converted to an interface type, it must be boxed because the interface is a reference type. 5.4:c. Clone (). No boxing is required, and the previous boxed object is called in the managed heap. Attached: In fact, the above is based on a fundamental principle, because the unboxed value type does not have a method table pointer, so the virtual method inherited on it cannot be called by value type. In addition, the interface type is a reference type. To this, I understand that the method table pointers are similar to C + + virtual function table pointers, which is an important basis for implementing the polymorphic mechanism of referencing objects.
9: How to Change a boxed object to a boxed object, because the specified method cannot be called directly, it must be disassembled before calling the method, but unpacking again creates a new stack instance and cannot modify the boxed object. A little dizzy, feel the tongue twister. For example: (Append a Change method in the example above) public void change (Int32 x) {this.x = x;} called: a A = new A (); a.x = 100; Object o = A; Boxed into O, below, want to change the value of O. ((A) o). Change (200); Did you get rid of it? Didn't get rid of it. The reason for this is that o when unpacking, a temporary stack instance A is generated, so the changes are based on temporary a, and are not changed to the boxed object. (Attached: in managed C + +, it is possible to directly change the instance reference from the first step when the unboxing is taken, but C # does not.) What's the best way to do that? Well, the same effect can be achieved by means of an interface. The implementation is as follows: interface Ichange {void change (Int32 x);} struct A:ichange {...} Call: ((Ichange) o). Change (200);//Did you get rid of it? Got rid of it. Why can we change now? When O is converted to Ichange, it will not be boxed again, certainly not unpacking, because O is already a reference type, and since it is a ichange type, you can call change directly, so the field in the boxed object is changed to achieve the desired effect.
10.--------------------------to convert a value type to a reference type, a boxing operation is required (boxing):
1. First allocate memory from the managed heap for the newly generated reference object.
2. Then copy the data of the value type to the memory you just allocated.
3. Returns the address of the newly allocated object in the managed heap.
As you can see, the two comparisons that are performed to allocate memory and copy data in a single boxing operation that affect performance.
Converting a reference inner type into a value type requires a unboxing operation (unboxing):
1. First get the address of the part of the managed heap that belongs to the value type, and this step is the strict unboxing.
2. Copy the values from the Reference object to the instance of the value type on the thread stack.
After these 2 steps, it can be considered that the same boxing is an interop operation. The strict unboxing does not affect performance, but the subsequent operation of the copied data will affect performance as well as the boxing operation. All types of
11, -------------------------net, are inherited by the base class System.Object, including the most commonly used underlying types: int, byte, short, bool and so on, which means that all things are objects. It is extremely inefficient to declare that these types are allocated memory in the heap at all times! (The reason and the difference between heap and stack will be said separately in another article!) ) . NET how to solve this problem? It is by dividing the type into value type (value) and reference type (regerencetype), C # The value types defined in include the original type (sbyte, Byte, short, Ushort, Int, Uint, Long, Ulong, Char, Float, Double, Bool, Decimal), enumerations (enum), structs (struct), reference types include: classes, arrays, interfaces, delegates, strings, and so on. The value type is to allocate memory in the stack, initialize it at the same time as stated, to ensure that the data is not NULL, the reference type is to allocate memory in the heap, initialize to NULL, the reference type needs to garbage collection to reclaim the memory, the value type does not need, out of scope, the system will automatically release! Here is the definition of boxing and unpacking! Boxing is the implicit conversion of a value type to a reference type object. For example: int i=0; Syste.object obj=i; This process is boxing! is to pack I! Unpacking is the conversion of a reference object into any value type! For example: int i=0; System.Object Obj=i; int j= (int) obj; The first 2 sentences of this process are the I boxing, the latter sentence is to remove obj box!
C # Boxing unboxing