I never dared to show the word "proficient" on my resume, but every time I have a resume recommendation, all kinds of "proficient" came into my eyes. Helpless. For example, I found this article during garden shopping today.ArticleThe boxing is discussed in the reply. I found that my original understanding is incorrect. So leave this memo.
Generally, when a value type instance needs to be converted to a reference type instance, it needs to be boxed. For example:
IntNumber =2;ObjectO = number; O. tostring ();
If you view its Il, you can find the box command. In general, for example, converting a value type instance cast to a reference type instance or a function parameter type (converted to reference type or cast as an interface ). But does the box command indicate that the packing operation has occurred? In fact, there are other cases.
First, value type can have its own static or instance members like other types, including methods (including virtual methods) and fields. Of course, we can call its virtual method, but when we must use the virtual function table to find the virtual function, we must boxing and then call virt, if you only use a member function to call the virtual function implementation of the Value Type instance, you do not need to use boxing. You can simply use the call command. For example:
IntNumber =3; Number. tostring ();
Its IlCodeYes:
Il_0001: LDC. i4.3 il_0002: stloc.0 il_0003: ldloca. s 00 il_0005: Call system. int32.tostring
Call the call method to trigger the instance method. It is not packed.
However, in this case, let the value type instance call its unimplemented virtual method:
VaRValueinstance =NewValueclass (); valueinstance. tostring ();
The following il code is generated:
Il_0001: ldloca. s 00 il_0003: initobj valueclassil_0009: ldloca. s 00 il_000b: Constrained. valueclassil_0011: callvirt system. Object. tostring
There is no box command, but there is a constrained. Command. Constrained. commands and callvirt are called constrained virtual call, which was introduced in CLR 2.0. The main purpose is to process the instantiation or method call of generic types, regardless of whether the actual parameter of the generic type is value type or reference type. However, the type parameters following the constrained. Command do not have to be generic parameters. They can be specific types directly. The Calling rules are as follows:
- If it is a reference type (in this case, the this pointer of this instance is a managed pointer pointing to this reference type instance), then the reference of the reference type instance is returned for this reference. The call of the virtual function occurs on the reference type instance.
- If it is a value type (the this pointer of this instance is a managed pointer, pointing to this value type instance), and the value type implements this function, then the next call is actually a non-virtual call, which directly works on the Value Type instance (this is because the value type is seal, the implemented virtual method cannot be used by other derived classes ).
- If it is a value type, And this type does not implement the virtual method of the base class (its base class must be system. object, system. valuetype or system. enum), then the reference of this pointer will return the value type instance, and it will be directly converted into object reference by boxing. Callback call applies to object reference.
We can see that the last one is the situation in the previous sample code.
Of course, boxing is also required to call non-Virtual Methods of the base class. For example:
VaRValueinstance =NewValueclass (); valueinstance. GetType ();
It is first boxed, and then calls the non-virtual method of the base class directly using call.
Il_0001: ldloca. s 00 il_0003: initobj valueclassil_0009: ldloc.0 il_000a: Box valueclassil_000f: Call system. Object. GetType
To sum up, packing may occur in the following situations:
- Value Type and reference type (Interface) type conversion, parameter transmission;
- Call the virtual method of the base class not implemented by the value type instance;
- Call the non-virtual method of the Value Type parent class.
Is there any other situation? Please add.