Boxing Day (No, not the day after Christmas)
| February 15, 2017 | in
The topic of object boxing and unboxing came up on our development Slack channel recently, so I realized that there might be a lot of developers out there who may not know or understand what boxing and unboxing of values are in C#.
In short, boxing is the process where a value type is converted to the type object or any interface type implemented by this value type.
Here is the original question that was posted in our Slack channel:
for an object in C#6 is item == null ? "null" : item.ToString() always equivalent to `item ?? "null"? (assuming ToString is NOT overriden)
While this may sound handy, this should be used with caution. Boxing and unboxing are computationally expensive processes. New objects must be allocated and constructed when new value types are boxed. The same is true for unboxing processes, although to a lesser degree.
So to try out what was being asked, I jumped in to LINQPad5 and prototyped a quick test with the following code:
object item = new object(); var result = item == null ? “null” : item.ToString(); var result2 = item ?? “null”; result.Dump(); result2.Dump();
The first result was a string, but the second one was actually an object. Another developer followed up to say that the null coalesce operation should be changed to the following to get the desired string output:
var result3 item?.ToString() ?? “null”
The original poster asked if they could be fine with the result being an object if it will be used in a function call that takes strings and just implicitly casts it to another string. That is when we started talking about the values being boxed and unboxed and how that would be a bad thing.
To determine performance, I ran three different methods in LINQPad. In the ten million executions run, I found that all three were pretty comparable in execution time but the null coalesce to string (result3) was consistently the best performer.