Does valueType.ToString () perform a listing on valueType?

let's say i have the following code in c #

int x = 0; x.ToString(); 

Does this internally box x? Is there any way to see how this comes from the visual studio?

+4
source share
2 answers

In this particular case, you are using System.Int32 (a int ). This type overrides ToString , Equals and GetHashCode , so there is no box.

If you use a struct that does not override ToString , then you will have constrained callvirt until System.Object.ToString() . Definition of constrained :

When the callvirt method command is prefixed with the specified restriction, the command is executed as follows:

  • If thisType is a value type, and thisType implements the method, then ptr is passed unchanged as the 'this' pointer to the invocation method instruction to implement the method with this type.
  • If thisType is a value type, and this type does not implement the method, then ptr is dereferenced, in the box, and passed as the 'this' pointer to the callvirt method instruction.

So, there is no box if the value type implements ToString , and there is a box if it does not implement it ... Interesting. I did not know.

For non-virtual methods, such as GetType() , which are defined in System.Object , the value type is always placed in the field. Just tested with:

 5.GetType(); 

IL code:

 IL_0001: ldc.i4.5 IL_0002: box [mscorlib]System.Int32 IL_0007: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType() 
+5
source

Here is the IL generated by your code:

  IL_0001: ldc.i4.0    
 IL_0002: stloc.0 // x
 IL_0003: ldloca.s 00 // x
 IL_0005: call System.Int32.ToString

As you can see, no boxing is happening.

On the other hand, this code

 object x = 0; x.ToString(); 

boxing will not be surprising:

  IL_0001: ldc.i4.0    
 IL_0002: box System.Int32
 IL_0007: stloc.0 // x
 IL_0008: ldloc.0 // x
 IL_0009: callvirt System.Object.ToString

In general, if type x not int , but any type of value ( struct ), you must override ToString to avoid boxing. In particular, constrained callvirt stands out:

  • If thisType is a value type, and thisType implements the method, then ptr is passed unchanged as the 'this' pointer to the invocation method instruction to implement the method with this type.

  • If thisType is a value type, and this type does not implement the method, then ptr is dereferenced, placed in a box, and passed as the 'this' pointer to the callvirt method command.

If you want to avoid boxing when calling Equals , GetHashCode and ToString by value type, you need to override these methods.

+6
source

Source: https://habr.com/ru/post/1500548/


All Articles