WO Central Developers | Design, Code, Test . . . Repeat?

Dec/09

4

Technical Screening: Boxing

I will be diving into a few questions that we use in our technical screenings for the WO Central development team.

Must a value type be boxed for a call to Object.GetType()?

To investigate this I will be using a struct (a struct is a value type). Take the following struct as an example.

struct Person
{
    public string FirstName;
    public string LastName; 

    public override string ToString()
    {
        return FirstName + " " + LastName;
    }
}

That’s pretty simple.

Now let’s make a call to GetType().

Person p;
p.FirstName = "Brian";
p.LastName = "Thoman"; 

Type t = p.GetType();

The C# compiler produces the following IL for the call to GetType().

L_001a: box TestBoxing.Person
L_001f: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()

Notice the explicit box instruction TestBoxing.Person. This happens because GetType() is a non-virtual method on System.Object.

Must a value type be boxed for a call to Object.ToString()?

Using the same Person struct, let’s take a look at ToString().

Person p;
p.FirstName = "Brian";
p.LastName = "Thoman"; 

String s = p.ToString();

For this call the compiler emits the following IL.

L_0027: constrained TestBoxing.Person
L_002d: callvirt instance string [mscorlib]System.Object::ToString()

The compiler places a constrained prefix to the callvirt instruction. This tells the CLR to do some checking before calling the virtual function. From the MSDN:

When a callvirt method instruction has been prefixed by constrained thisType, the instruction is executed as follows:

  • If thisType is a reference type (as opposed to a value type) then ptr is dereferenced and passed as the ‘this’ pointer to the callvirt of method.
  • 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.

This simply means that if the value type implements the virtual function it does not need to be boxed. If the value type does not implement the virtual method it will be boxed and the ancestor class’ method will be called.

So…

Must a value type be boxed for a call to Object.GetType()?

yes – all the time (remember the explicit box instruction)

Must a value type be boxed for a call to Object.ToString()?

it depends on if the value type overrides ToString() and provides its own implementation.  It also makes sense that calling base.ToString() in the Person class’ ToString() implementation will box.

RSS Feed

No comments yet.

Leave a comment!

<<

>>

Find it!

Theme Design by devolux.org