C# Boxing And Unboxing

What Is Boxing and Unboxing

There’s a lot to unpack in this topic (pun intended) so let’s get started. I’ve found this topic to be a bit misunderstood, even by some more experienced developers, so I’d like to cover this topic in this post. I see this periodically in some of the code that I work with and wanted to show a couple of examples and then layout what the implications are and why this is sometimes done. The long and the short of this is that we can take either a reference type (most commonly think an object, class, struct, or interface) or value types (int, double, float, etc.) and then create a new object with that reference and add it to the heap using System.Object as a wrapper. I’ve covered previously the difference between heap and stack memory reference types, and you may want to brush up on those as well.

Example Code

Of course, no explanation of such a topic is complete without a code example. This is a very simple example, but I feel it gets the idea across easily and helps to show you the implications of boxing and unboxing in C#. When we create and instance of System.Object and set it to equal our previous created type this is called boxing. And unboxing is the opposite equivalent of taking our System.Object type and casting it back to the original type (value type, or class, struct, etc…). The boxing portion is considered implicit as we are casting to the System.Object, and then to unbox we must be explicit in our unboxing and make sure we are casting our unboxed type correctly.

using System;
 
namespace BoxingUnboxing
{
    class Person
    {
        public string Name { get; }
        public int Age { get; }
 
        public Person(int age, string name)
        {
            Age = age;
            Name = name;
        }
    }
 
 
    class Program
    {
        static void Main(string[] args)
        {
            var person = new Person(35, "Nick");
            object oPerson = person; //Boxing
            Person samePerson = (Person)oPerson;//Unboxing
 
            Console.WriteLine($"{samePerson.Name}"); // Nick
            Console.WriteLine($" These are the same person: {samePerson == person}"); //Evaluates to True
 
            int fifty = 50;
            object oFifty = fifty; //Boxing
            int newFifty = (int)oFifty//Unboxing
            Console.WriteLine(fifty); //50
            fifty = 25;
            Console.WriteLine(fifty == (int)oFifty); //Evaluates to False as fifty now == 25 and oFifty == 50
        }
    }
 
 
}

Looking at Reference Types

You’ll notice in this case that boxing/unboxing works for both reference types and value types. Also, you’ll notice that both can be cast directly to an object. This is great, but also you need to understand that we are creating a reference on the heap to our reference type so that we are actually able to modify the original object and see the change reflected in our reference or the unboxed reference. This is pretty expected behavior for reference types. And remember that both the original object and the reference both sit on the heap memory.

Looking at Value Types

This one is a bit tricky. Because our original value type is an integer, it’s going to have a memory allocation on the stack. This is expected. Now because we have boxed our int to an object there is a newly created object that is made and which has a reference on the heap. Once this happens the newly created object does is not able to maintain a reference to the original value type. Thus when we attempt to compare the two, we get an evaluation to false. Interesting right!

What Are Some Use Cases?

I have used boxing and unboxing at times when it comes to serialization and deserialization of objects into JSON (there are a few different libraries to handle this for you if you need). Although not always common, this does happen occasionally. One advantage of boxing is that you can pass for example an integer around as an object, and then after unboxing it, you get you native integer performance back. I would also like to point out that there is a performance impact when performing boxing and unboxing, and depending on what is being done, this should be used with caution, and in my opinion, avoided if possible.

Leave a Reply

Your email address will not be published. Required fields are marked *