A study of Visual C # boxing and unboxing

Source: Internet
Author: User
Tags constructor manual mscorlib reference tostring wrapper
Visual C # Boxing and unboxing research
2004-09-15 Author: Origin: CSDN

Before we begin to discuss this issue, we may wish to ask a few questions to systematically understand the subject we are exploring today.

The viewer may have used countless classes, such as the System.Console class or the. NET class library, many times. So, what I want to ask is where do they come from? How does C # contact them? Is there a mechanism or type system that supports our personalized extensions? What types of systems are available for us to use? If we do not know the problems of these pl, even if they do not know the reason, C # door is afraid to shut us out.
Then let us stop the work in hand, the idea of a clue, to act. NET important technology and foundation of one of the CTS (Common Type System) do an interesting research. As the name suggests, the CTS is a common type system that exists to implement the rules that must be followed when an application declares and uses these types. In this to insert a sentence, although perhaps everyone is familiar with this, but I would like to emphasize that. NET divides the type of the entire system into two broad categories-value types and reference types. In this, you may be Nu scold: said so long, you seem not to cut to the chase! Don't panic! Got it. NET type system does not mean that you really understand the principle of this type of system and the meaning of existence.
Most object-oriented languages have two types: the original type (the intrinsic type of the language, such as integers, enumerations), and classes. Although object-oriented technology embodies a strong ability to achieve modularity and visualization, there are also problems, such as the system type issue now mentioned, history tells us that two sets of types cause many problems. The first is compatibility, and this is one of the things Microsoft has been hard to criticize, because most OO languages have this weakness because their original types have no common basis, so they are not real objects in nature, they are not derived from a common base class. No wonder, Anders Heijlsberg laugh called it "magic type."

It is because of this flaw that when we want to specify a method that accepts any type of parameter supported by this language, the same problem is again harassing our brain-incompatible. Of course, for C + + PL Montana, perhaps this is no big deal, they will be proud to say, as long as the overload of the constructor for each of the original type to write a wrapper Class is not over! Well, it's a good thing to be able to coexist, but how do we get the most out of this trick--the result? As a result, they will still be confident to open boarland, skilled writing a overloaded function to get the results from the wrapper Class just now. Brothers or sisters, in the historical conditions of the time, your actions are pioneering, but as opposed to the present, you will pay the price-inefficient. After all, C + + is more dependent on objects than on object-oriented. It is more sensible to admit reality than to die. Spend so much effort, finally put the matting finished, I want to say is:. NET environment has brought us convenience. First, all things in the CTS are objects; second, all objects originate from a base class--system.object type. This is the so-called single root hierarchy (singly rooted hierarchy) for more information on System.Object please refer to Microsoft technical documentation. Here we briefly talk about the two major types mentioned above: Value type and Reference type.

One of the biggest features of a CTS value type is that they cannot be null, and the implication is that a variable of a value type always has a value. In C #, it includes the original type, struct, enumerator. One thing to emphasize here is that when passing a variable of a value type, we actually pass the value of the variable, not the reference to the underlying object, as opposed to the variable passing the reference type; the CTS reference type is like a type-safe pointer, which can be null. It includes types such as classes, interfaces, delegates, arrays, and so on. When we assign a reference type, the system assigns a value (memory allocation and location) to the stack on the background, and returns a reference to the value, which, when null, indicates that there is no reference or type pointing to an object. This means that when we declare a variable of a reference type, we are manipulating the reference (address) of the variable, not the data.

When discussing this place, the protagonist of this article finally shines debut-to vomit blood or vomit comrade, please endure again. I would like to ask a question first: how to effectively expand and improve the performance of the system when using this type of multiple systems? Maybe it's the question on the blackboard, and the Seattle guys are proposing the idea of box and UnBox (unpacking). To put it simply. Boxing is the process of converting a value type to a reference type (reference type), or, conversely, a unboxing. (In fact, this idea was created in the first eight lifetimes). Here we will discuss the process of boxing and unboxing in further detail. In the discussion, the answer to the question we have just mentioned will be solved.

First, let's look at the boxing process, for which we need to do two things first: 1, write routines; 2, open ildasm (MSIL Code view tool) so we'll take a look at the following code:

Using System;

Namespace Structapp
{
///
Summary description of the Boxandunbox.
///
public class Boxandunbox
{
Public Boxandunbox ()
{
//
TODO: Add constructor logic here
//
}
/////////////////////////////////////////////////////////////////////////////////////
static void Main (string[] args)
{
Double dubbox = 77.77; Define a value-form variable
Object objbox = Dubbox; Boxing the value of a variable into a reference object
Console.WriteLine ("The Value is ' {0} ' and" Boxed is {1} ", dubbox,objbox.tostring ());
}
/////////////////////////////////////////////////////////////////////////////////////
}
}

In the code, we just need to focus on two lines of code that are annotated with the main () method, and the first line we create a double type variable (dubbox). Clearly according to the rules, the CTS rules double is the original type, so Dubbox nature is a variable of the value type; the second line actually does three jobs, which is clear in the MSIL code below. The first step is to remove the value of the Dubbox, the second step is to convert the value type to the reference type, and the third pass the value to Objbox.

The MSIL code is as follows:

. method private Hidebysig static void Main (string[] args) cil managed
{
. entrypoint
Code size (0x28)
. maxstack 3
. Locals init ([0] float64 Dubbox,
[1] Object Objbox)
IL_0000:LDC.R8 77.769999999999996
il_0009:stloc.0
il_000a:ldloc.0
Il_000b:box [mscorlib]system.double
Il_0010:stloc.1
Il_0011:ldstr "The Value is ' {0} ' and the Boxed is {1}"
il_0016:ldloc.0
Il_0017:box [mscorlib]system.double
Il_001c:ldloc.1
Il_001d:callvirt instance string [Mscorlib]system.object::tostring ()
Il_0022:call void [Mscorlib]system.console::writeline (String,
Object
Object
Il_0027:ret
}//End of method Boxandunbox::main

In MSIL, the il_0000 to il_0010 lines describe the first two lines of code. Refer to the MSIL Manual for C #, it is not difficult for the viewer to understand the execution of this low-level code, and I would like to highlight the story that occurs when Dubbox is boxed: (1) Dividing the stack memory, allocating memory on the stack = dubbox size + objbox and the space occupied by its structure; (2) The value of Dubbox (77.7699999999996) is copied to the newly allocated stack, (3) the address stack that will be assigned to Objbox, at which point it points to an object type, that is, a reference type.

Unboxing as a boxing counter process, it seems very simple, in fact, there are many values of the thinking of things. First of all, in box, we don't need explicit type conversions, but we have to do type conversions when unbox. This is because the object of the reference type can be converted to any type. (Of course, this is also a difference between the computer and the human brain) type conversion will be subject to monitoring from CTS Management Center-the standard is naturally based on rules. (Its content is enough to set a chapter to discuss) OK, let's take a look at the following code first:

Using System;

Namespace Structapp
{
///
Summary description of the Boxandunbox.
///
public class Boxandunbox
{
Public Boxandunbox ()
{
//
TODO: Add constructor logic here
//
}
/////////////////////////////////////////////////////////////////////////////////////
static void Main (string[] args)
{
Double dubbox = 77.77;
Object objbox = Dubbox;
Double Dubunbox = (double) objbox; Unpacking a Reference object and returning a value
Console.WriteLine ("The Value is ' {0} ' and the unboxed is {1}", Dubbox,dubunbox);
}
/////////////////////////////////////////////////////////////////////////////////////
}
}

This code adds a double Dubunbox = (double) objbox to the code in front of it, and the new line of code does four jobs, which is also reflected in the MSIL code. The first step pushes a value into the stack; the second step converts the reference type to a value type; the third step indirectly pushes the value of the stack; the fourth step passes the value to the Dubunbox.

The MSIL code is as follows:

. method private Hidebysig static void Main (string[] args) cil managed
{
. entrypoint
Code size (0x30)
. maxstack 3
. Locals init ([0] float64 Dubbox,
[1] Object Objbox,
[2] float64 Dubunbox)
IL_0000:LDC.R8 77.769999999999996
il_0009:stloc.0
il_000a:ldloc.0
Il_000b:box [mscorlib]system.double
Il_0010:stloc.1
Il_0011:ldloc.1
Il_0012:unbox [mscorlib]system.double
IL_0017:ldind.r8
Il_0018:stloc.2
Il_0019:ldstr "The Value is ' {0} ' and the unboxed is {1}"
il_001e:ldloc.0
Il_001f:box [mscorlib]system.double
Il_0024:ldloc.2
Il_0025:box [mscorlib]system.double
Il_002a:call void [Mscorlib]system.console::writeline (String,
Object
Object
Il_002f:ret
}//End of method Boxandunbox::main

In MSIL, the il_0011 to il_0018 Line describes the new line of code. Referring to the MSIL Manual of C #, it is not difficult for the viewer to understand the execution of the underlying code, here I would like to highlight the Objbox in the case of unpacking: (1) The environment must first determine the address of the legitimate object on the stack, and if the object to the specified type of conversion is legitimate, if not legitimate, throw an exception; (2) When the judgment type is converted correctly, a pointer to the value within the object is returned.

It seems that packing and unpacking is just the same, the cost of half a day to put the ' value ' to the ' box ', there is more effort to dismantle it, depressed Ah! The observant viewer, may also be able to combine code and MSIL see, how in the call Console.WriteLine () in the process and appeared two times box, yes, I would like to escape this section, but since has been found, it should be bold face, in fact, this is the legendary "black box operation" Ah! Because the Console.WriteLine method has many overloaded versions, where the version is based on two string objects, and the overload of the parameter with type object is the closest version found by the compiler, the compiler, in order to obtain the same prototype as this method, The Dubbox and Dubunbox of a value type must be boxed (converted to a reference type) separately.

Therefore, in order to avoid the loss of performance due to unnecessary implicit boxing, it is best to box the value before performing these multiple-type overloaded methods. Now we're going to improve the code above to:

Using System;

Namespace Structapp
{
///
Summary description of the Boxandunbox.
///
public class Boxandunbox
{
Public Boxandunbox ()
{
//
TODO: Add constructor logic here
//
}
///////////////////////////////////////////////////////////////////
static void Main (string[] args)
{
Double dubbox = 77.77;
Object objbox = Dubbox;
Double Dubunbox = (double) objbox;
Object objunbox = Dubunbox;
Console.WriteLine ("The Value is ' {0} ' and the unboxed is {1}", Objbox,objunbox);
}
///////////////////////////////////////////////////////////////////
}
}

MSIL Code:

. method private Hidebysig static void Main (string[] args) cil managed
{
. entrypoint
Code size (0x2d)
. maxstack 3
. Locals init ([0] float64 Dubbox,
[1] Object Objbox,
[2] float64 Dubunbox,
[3] Object Objunbox)
IL_0000:LDC.R8 77.769999999999996
il_0009:stloc.0
il_000a:ldloc.0
Il_000b:box [mscorlib]system.double
Il_0010:stloc.1
Il_0011:ldloc.1
Il_0012:unbox [mscorlib]system.double
IL_0017:ldind.r8
Il_0018:stloc.2
Il_0019:ldloc.2
Il_001a:box [mscorlib]system.double
Il_001f:stloc.3
Il_0020:ldstr "The Value is ' {0} ' and the unboxed is {1}"
Il_0025:ldloc.1
Il_0026:ldloc.3
Il_0027:call void [Mscorlib]system.console::writeline (String,
Object
Object
Il_002c:ret
}//End of method Boxandunbox::main

I'm dizzy! That's a good thing! After reading is not the blood of vomiting blood, the hanged hanged! I believe that the comrade who can stick to the last one "!" must be a good comrade.

In fact, we can speculate that the reference type should belong to the advanced type, and the value type belongs to the original type, and the box is just a concept, an order, a set of rules or a logic. The original thing as a foundation, its complexity and logic is not very high, and the advanced things are not so stable, it will continue to evolve and develop, because the logic of the ' box ' will constantly be required to expand and improve. In this way, it is not difficult to predict where we need to go in the future and where our chances of success may exist ——!




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.