What are boxing and unboxing in C#?

Özkan ARDİL
4 min readJan 12, 2024

--

In C#, boxing and unboxing are operations related to converting between value types and reference types.

In a different way I can say that boxing is the process of converting a value type to the System.Object type. Unboxing is the opposite — the process of converting the boxed value back to a value type. When the value is boxed, it is wrapped inside an instance of the System.Object class and stored on the heap.

To understand what boxing and unboxing are, it is essential to understand what value and reference types are. You can refer to “What is the difference between value types and reference types in C#?” article below.

As we know, value types are stored on the stack while reference types are stored on the heap. Only the reference itself (so an “address” or “pointer” to the object stored on the heap) is stored on the stack.

Let’s continue with a real-life example.

int num = 10; // Value type
string word = "Özkan"; // Reference type

In this situation the following data is stored in the memory:

● On the stack;

  • The value of number variable (10), as an integer is a value type,
  • The reference to the word variable stored on the heap, as string is a reference type.

● On the heap;

  • The value of the word variable (“Özkan”).

Boxing Example

When a value type (such as int, float, bool, etc.) is assigned to a variable of a reference type (like object), the value is 'boxed' into an object.

Essentially, the value type gets wrapped in an object of the corresponding type.

Let’s box num variable.

int num = 10; // Value type
string word = "Özkan"; // Reference type
object boxedNum = num; // Boxing: Implicitly converting 'num' to an object

In this case, the int value 10 is boxed into an object type. The compiler implicitly performs this boxing operation.

A new variable of a type object is created. The object is a reference type, so its value is stored on the heap.

Let’s see the state of the stack and the heap now:

● On the stack;

  • The value of number variable (10), as an integer is a value type,
  • The reference to the word variable stored on the heap,
  • The reference to the boxedNumber variable stored on the heap.

● On the heap;

  • The value of the word variable (“Özkan”),
  • The value of the boxedNumber variable (10).

Unboxing Example

Unboxing, on the other hand, is the process of extracting the value type from the boxed object. It’s the reverse of boxing and must be done explicitly by casting the object back to its original value type.

int unboxedNum = (int)boxedNum; // Unboxing: Explicitly converting 'boxedNum' to an 'int'

Here, (int) is used to explicitly cast boxedNum (which contains the boxed int value) back to its original int value.

Implicit Boxing and Explicit Unboxing

The key point to remember is that boxing is done implicitly by the compiler when a value type is assigned to a reference type variable. However, unboxing must be explicitly performed by the programmer using a cast operation.

Performance Implications

Boxing and unboxing can impact performance, especially in scenarios where these operations occur frequently. They involve memory allocations and type conversions, which might lead to performance overhead in certain situations.

When to Use

It’s essential to understand the implications of boxing and unboxing while designing code. In performance-critical applications, minimizing these operations can be beneficial. However, in certain cases where working with collections or interfaces that expect reference types is necessary, these operations might be unavoidable.

You’ll find the exact place of the boxing and unboxing in a real scenario given below.

List<object> myList = new List<object>();

int value = 20;
myList.Add(value); // Boxing occurs here

int retrievedValue = (int)myList[0]; // Unboxing occurs here

Conclusion

Boxing and unboxing provide a way to treat value types as objects and vice versa, enabling flexibility in C# programming. However, it’s crucial to be mindful of their performance implications, especially in scenarios where efficiency is critical.

Understanding these concepts helps in writing more efficient and optimized code while harnessing the benefits of working with both value types and reference types in C#.

👏 If you found the content useful, I would appreciate it if you could support it with applause (you can also contribute with more than one applause by holding down the clap button for a long time).

⬇️ Check out my other articles.

💬 Let me know in the comment section what have I missed? Where I was wrong?

👨‍👦‍👦 You can also share this article with your friend. Argue a little about it. It is known that the truth is born in a dispute.

🙃 Stay determined, stay focused, and keep going.

Thanks for reading…

--

--

Özkan ARDİL

.NET C# JS and Angular dev with 8+ yrs exp, self-taught & passionate web developer. Sharing tips & experiences in C# and web dev.