Avoid boxing / unboxing in method calls

I tried to understand the effect of boxing / unpacking during method calls from Essential C # 6.0 (MarkMichaelis and EricLippert), and in the end I was more confused than I started.

Here is the code from the book:

struct A { public int Val {get; set;}; //doesn't override ToString } A vo = new A();; object thing; // Boxing thing = vo; string text = ((A)thing).ToString(); Console.WriteLine(text); 

Further, the author writes the following:

If the receiver is unpacked and the structure does not override ToString (), the implementation of the base class must be called, and this expects a reference to the object as the receiver. Consequently, the receiver is boxed.

This is the case with the code above, where the translation operator on A will disable the β€œthing” and then try to call ToString in the temporary. Since the ToString () method was not overridden in structure A, the ToString call should only occur after the temporary code generated by the cast (A) is again placed in the box or if the compiler completely disables decompression / boxing.

But the generated CIL, as shown below, does show that the β€œthing” has been unpacked, but the call to ToString () occurs without re-enabling it. Please help me figure this out.

 .locals init (valuetype Chapter7.A V_0, object V_1, string V_2, valuetype Chapter7.A V_3) IL_0000: nop IL_0001: ldloca.s V_0 IL_0003: initobj Chapter7.A IL_0009: ldloc.0 **IL_000a: box Chapter7.A** //thing = vo IL_000f: stloc.1 IL_0010: ldloc.1 **IL_0011: unbox.any Chapter7.A** //((A)thing) IL_0016: stloc.3 IL_0017: ldloca.s V_3 //the temporary where unboxed value is stored IL_0019: constrained. Chapter7.A IL_001f: callvirt instance string [mscorlib]System.Object::ToString() 
+5
source share

All Articles