Skip to Content
Course content

249: Common C# Interview Questions on Boxing and Unboxing

Click on the "Edit" button in the top corner of the screen to edit your slide content.

If you've spent any time prepping for C# interviews, you've probably seen "Boxing and Unboxing" pop up. On the surface, it seems like a trivial detail, but interviewers love it because it tests whether you actually understand how the .NET runtime manages memory. It's the difference between someone who just knows the syntax and someone who knows what's happening under the hood.

Think of it like shipping a fragile piece of jewelry. A value type (like an int or a bool) is like a loose ring. It's small, it's efficient, and you can keep it right in your pocket (the stack). But if you need to send that ring through a courier service that only accepts standardized shipping boxes (the heap), you can't just hand them the ring. You have to put the ring inside a box. Now, the courier doesn't care what's inside; they just see a "Box" (an object). When the recipient gets the package, they have to open the box to get the ring back out. That's unboxing.

Mapping the Box to the Code

In C#, boxing is the process of converting a value type to the type object or to any interface implemented by this value type. Unboxing is the explicit conversion back.

int myAge = 30;             // Value type (on the stack)
object boxedAge = myAge;      // Boxing: The int is wrapped in an object and moved to the heap
int unboxedAge = (int)boxedAge; // Unboxing: Extracting the value back to the stack

Here is exactly what happened there: when I assigned myAge to boxedAge, the CLR allocated a piece of memory on the managed heap, copied the value of the integer into that memory, and gave me a reference (a pointer) to that location. I didn't just change the label; I actually moved the data.

The Performance Tax

This is the part where interviewers usually dig in. They'll ask: "Why is boxing bad?" The answer isn't that it's "forbidden," but that it's expensive. Boxing requires a heap allocation and a memory copy. Unboxing requires a type check and another copy. If you do this in a loop a million times, you're creating a million objects on the heap that the Garbage Collector (GC) eventually has to clean up. I've seen legacy codebases where the GC was spiking because someone was boxing integers inside a high-frequency trading loop. It's a silent performance killer.

The Danger of the Wrong Box

One tricky interview question involves unboxing to the wrong type. Remember: unboxing is strict. You cannot unbox a value into a different type, even if that type is compatible via implicit conversion.

int number = 42;
object boxed = number;

// This will compile, but throw an InvalidCastException at runtime!
double wrongType = (double)boxed; 

You might think, "Wait, an int can fit into a double!" That's true for standard conversions, but unboxing is different. The runtime looks at the "box" and says, "This box contains an int. You asked for a double. I can't do that." You would have to unbox it as an int first, and then cast it to a double.

Why Generics Fixed This

If you're asked how to avoid boxing, the answer is almost always Generics. Before C# 2.0, we had the ArrayList, which stored everything as object. Every single value type added to an ArrayList was boxed. When List<T> arrived, we could finally tell the list, "You are specifically a list of integers." This allows the runtime to keep the integers as value types on the stack (or within the contiguous array on the heap), completely bypassing the need for boxing.




📋 Practical Task

Refactoring the Legacy Value Cache

You've inherited a legacy piece of code that uses a non-generic ArrayList to cache system settings. This is causing significant GC pressure in a high-performance environment. Your task is to refactor the SettingsCache class to eliminate boxing and unboxing.

Current Broken Code:

using System.Collections;

public class SettingsCache {
    private ArrayList _settings = new ArrayList();

    public void AddSetting(int value) {
        _settings.Add(value); // Boxing happens here
    }

    public int GetSetting(int index) {
        return (int)_settings[index]; // Unboxing happens here
    }
}

Your Requirements:

  • Replace the ArrayList with a generic List<T>.
  • Ensure that AddSetting and GetSetting no longer perform any boxing or unboxing operations.
  • Update the necessary using directives to support your changes.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.