lets say, i have the following code in c#
int x = 0;
x.ToString();
does this internally does a boxing of x? Is there a way to see this happening from visual studio?
lets say, i have the following code in c#
int x = 0;
x.ToString();
does this internally does a boxing of x? Is there a way to see this happening from visual studio?
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 taking place.
On the other hand, this code
object x = 0;
x.ToString();
will not surprisingly cause boxing:
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
Generally, if if the type of x
is not int
but any value type (struct
) then you have to override ToString
to avoid boxing. Specifically, a constrained callvirt
is emited:
If thisType is a value type and thisType implements method then ptr is passed unmodified as the 'this' pointer to a call method instruction, for the implementation of method by thisType.
If thisType is a value type and thisType does not implement method then ptr is dereferenced, boxed, and passed as the 'this' pointer to the callvirt method instruction.
If you want to avoid boxing when calling Equals
, GetHashCode
and ToString
on a value type you need to override these methods.
In this specific case, you are using a
System.Int32
(anint
). That type redefinesToString
,Equals
andGetHashCode
, so no boxing.If you use a
struct
that doesn't redefineToString
what you'll have is aconstrained callvirt
toSystem.Object.ToString()
. The definition of constrained:So there isn't boxing if the value type implements
ToString
and there is boxing if it doesn't implement it... Interesting. I didn't know.For non-virtual methods like
GetType()
that are defined inSystem.Object
the value type is always boxed. Just tested with a:resulting IL code: