C # Boxing and unpacking

Source: Internet
Author: User

1.
Boxing and unpacking is an abstract concept.
2.
Boxing is converting a value type to a reference type; unpacking is converting a reference type to a value type
With boxing and unboxing, you can link value types to reference types by allowing any value of a value type to be converted to a value of type Object
For example:
int val = 100;
Object obj = val;
Console.WriteLine ("Value of object = {0}", obj);
This is a boxed procedure, which is the process of converting a value type to a reference type

int val = 100;
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 in the box can be removed
3.
. NET, the data type is divided into a value type and a reference (not a pointer to C + +) type, corresponding to this, memory allocation is divided into two ways, one for the stack, two for the heap, note: is the managed heap.
Value types are only allocated in the stack.
The reference type allocates memory to the managed heap.
The managed heap corresponds to garbage collection.

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.
Packing:
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:
Check the object instance to make sure 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: Effect of packing/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 a 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: Further understanding of packing/unpacking
Boxing/unpacking is not as simple as the above, such as: when boxing, to refer to the 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.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 the boxed object  
for a boxed object, because the specified method cannot be called directly, it must be disassembled before the method is called, but the new stack instance will be generated when the container is disassembled again, and the boxed object cannot be modified. A little dizzy, feel the tongue twister. For example: (Append the Change method in the example above)  
public void Change (Int32 x) { 
this.x = x; 

Call: 
A A = new A ();  
a.x = 100; 
Object o = A;//boxing into O, below, to change the value of O.  
((A) o). Change (200); Did you get rid of it? Didn't get rid of it.   The reason why the
is not changed is that when unpacking, a temporary stack instance A is generated, so the change is based on temporary a, not 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 good of that?  
Well, the same effect can be achieved by means of an interface.  
is implemented as follows:  
interface Ichange { 
void Change (Int32 x);  

struct A:ichange {& nbsp
...  

Call:  
((Ichange) o). Change (200);//Did you get rid of it? Got rid of it.  
Why can I change now?  
when the O is converted to Ichange, there is no unboxing, of course, because O is already a reference type, and since it is a ichange type, you can call change directly, so the fields in the boxed object are changed. Achieve the desired effect.

10, --------------------------
       Converts 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 thought that the same boxing is the reciprocal 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.

11.-------------------------
NET all types are inherited by the base class System.Object, including the most commonly used underlying types: int, byte, Short,bool, and so on, meaning 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 values (value) and reference (Regerencetype), the value types defined in C # include the original type (Sbyte, Byte, short, Ushort, Int, Uint, Long, Ulong, Char, Float, Double, Bool, Decimal), enum (enum), struct (struct), reference types include: class, Array, interface, delegate, string, 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 garbage collection to reclaim the memory, the value type does not need, exceeds the 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. Like what:
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! Like what:
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 and unpacking

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.