Basic knowledge of C # basics (18) Boxing and unpacking of value types (i)

Source: Internet
Author: User
It is interesting to know carefully about boxing and unpacking, first of all, why boxing and unpacking?
Look at the following section of code:

    Class program    {        static void Main (string[] args)        {            ArrayList array = new ArrayList ();            Point p;//assigns a for            (int i = 0; i < 5; i++)            {                p.x = i;//initialization value                p.y = i;                Array. ADD (P);//Boxing}} public struct-point        {public        Int32 x;        Public Int32 y;    }

Loop 5 times, initializing a point value type field each time, and then dropping it into ArrayList. A struct is a structure of a value type, so what is stored in ArrayList? Let's look at the Add method of ArrayList. You can see the Add method in MSDN:
public virtual int Add (Object value),
You can see that the argument to the Add is the object type, which is the argument that it needs to be a reference to one of the objects. This means that the argument must be a reference type. As to what is a reference type, it is not necessary to elaborate, nothing more than a reference to an object on the heap. But here for the sake of understanding, say again the heap and stack.
1. Stack (stack)-Automatically allocated by the compiler to release, store the function parameter value, local variable value and so on.
2. Heap area-allocated by the programmer to release, if the programmer does not release, the end of the program may be recycled by the OS.
For example, the following:

 class program {static void Main (string[] args) {Int32 n;//This is a value type, stored in the stack        , the Int32 initial value of 0 a a;//opens up space a = new A () in the stack;//An object that is actually instantiated is saved in the heap. }} public Class A {public A () {}} 

Back to the question above, the Add method needs to reference the parameter of the type, what to do? That's going to use boxing, so-called boxing, which is to convert a value type to a reference type. The process of conversion is this:
1. Allocate good memory in the managed heap. The amount of memory allocated is the amount of memory required for each field of a value type plus two additional members (type object pointer and Synchronous block index) for all objects of the managed heap.
2. The value type of the field is copied to the newly allocated pair of memory.
3. Returns the address of the object. At this point, the address is a reference to an object, and the value type is now converted to a reference type.
Thus, in the Add method, a reference to a boxed point object is saved. The boxed object is always in the heap and knows the programmer's handling or system garbage collection. At this point, the life cycle of the boxed value type exceeds the life cycle of the unboxed value type.
With the above box, the natural need to unpack, if you want to remove the array of the NO. 0:
Point P = (point) array[0];
The thing to do here is to get a reference to the element 0 of ArrayList and place it in the point value type P. To achieve this, how to do this, first, get the address of each point field of the boxed point object. This is the unpacking. The values contained in these fields are then copied from the heap to the stack-based value type instance. Unpacking is actually the process of getting a reference that points to the original value type contained in an object. In fact, the reference points to the unboxed part of the boxed instance. Therefore, unlike boxing, unpacking does not require any bytes to be copied in memory. However, there is a point where the copy of the field occurs immediately after unpacking.
So boxing and unpacking can have an adverse effect on the speed and memory consumption of the program, so be aware of when the program will automatically carry out boxing/unpacking, and try to avoid these when writing code.
When unpacking, be aware of the following exceptions:
1. NullReferenceException is thrown if the variable containing the reference to the boxed value type instance is null.
2. InvalidCastException is thrown if the referenced object is not a boxed instance of the expected value type.
For example, the following code snippet:

             Int32 x = 5;            Object o = x;            Int16 r = (Int16) o;//throws InvalidCastException exception

Because it can only be converted to a value type when it was not boxed when unpacking. Modify the above code to:

             Int32 x = 5;            Object o = x;            Int16 r = (Int16) o;//throws InvalidCastException exception            Int16 r = (Int16) (Int32) O;

Right at this point.
After unpacking, a field copy occurs, with the following code:

            The field replication point            P1 occurs;            p1.x = 1;            P1.Y = 2;            Object o = p1;//boxed, replication            p1 = (point) o;//unboxing, and the field is copied from the boxed instance to the stack

Let's look at the following code snippet:

            To change the boxed value of point            P2;            p2.x = ten;            P2.Y =;            Object o = p2;//boxing            P2 = (point) o;//unboxing            p2.x = 40;//Changes the value of the variable in the stack            o = p2;//again boxing, o referencing the new boxed instance

The purpose here is to change the value of the boxed P2 x to 40 so that it is necessary to remove the box first, perform a copy of the field to the stack, change the value of the field in the stack, and then perform a boxing once, and then create a new boxed instance on the heap. As a result, we also see the impact of boxing/unpacking and replication on program performance.
Let's look at several code snippets for packing and unpacking:

            Packing Unpacking demo            Int32 v = 5;            Object o = v;            v = 123;            Console.WriteLine (v + "," + (Int32) o);

This happened 3 times in the box, but it is clear that

            Object o = v;            v = 123;

But there was a boxing in the Console.WriteLine, why? Because the WriteLine in this case is a string type argument, and string is known to be a reference type, the (Int32) O is also boxed here. Here again to explain the use of the + number in the program connection string problem, when the connection there are several value types, then a few boxing operations.
However, the code above can be modified:

            Modified after            Console.WriteLine (v.tostring () + "," + O);

This will not be boxed.
Then look at the following code:

Int32 v = 5;            Object o = v;            v = 123;            Console.WriteLine (v);            v = (Int32) o;            Console.WriteLine (v);

Here only one boxing, that is, object o = v here, and Console.WriteLine due to overloading the int,bool,double and so on, so here does not occur boxing.

The above is the basic knowledge of C # basics (18) Boxing and unpacking of value type (a), more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!

  • 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.