Boxing/unboxing in .NET [closed]
It seems like a big deal is made out of boxing and unboxing. Are there so many uses of the object type that we really have to be super aware of this?
What are very practical instances when boxing/unboxing is needed?
It depends.
I think that it's currently less of an issue than it was previously. If you make sure to use the generic collections within the framework (ie: use List<T>
instead of ArrayList
), then it will likely not be a major issue for you.
This was a huge issue in .NET 1.1, as most collections worked on object
, since there were no generic collections. In .NET 1.1, every time you added an int
, for example, into most collections, it got boxed, and every time you pulled it out, it was unboxed. If you were doing this in a tight loop, there could easily be problems. It also caused many errors such as trying to unbox and convert into the inappropriate type, which raises an exception.
The difference is the following:
In .NET 1.1, you would typically use something like an ArrayList
:
ArrayList list = new ArrayList();
list.Add(1); // These are all boxing - the integer is getting boxed to add
list.Add(2);
list.Add(3);
foreach(object item in list)
{
// Unboxing required here:
int value = (int)item;
Console.WriteLine(value);
}
Even worse, since this isn't type safe, you could easily cause serious problems since an unbox and conversion can't happen in a single operation:
foreach(object item in list)
{
// Trying to unboxing into the wrong type here...
// This will raise an exception at runtime, but compile fine!
double value = (double)item;
Console.WriteLine(value);
}
In .NET 2 and later, however, you could use generic collections:
List<int> list = new List<int>();
list.Add(1); // No boxing now, since it's using generics!
list.Add(2);
list.Add(3);
foreach(int value in list) // This is now typesafe, and doesn't cause an unboxing operation
{
Console.WriteLine(value);
}
Boxing and unboxing is still needed today at times. For example, Reflection works entirely on object
and not concrete types, so it requires boxing of values in order to use methods like FieldInfo.SetValue.
Boxing/unboxing is needed when you want to treat a value type (information that is passed by copying the value instead of passing a reference, pointer, to it) like a reference type (you just copy a pointer.) To do that, you have to create an object with the value, and then get that value whenever you want to perform an operation on it. It's a lot of overhead compared to just use the value - you have to create an object, and destroy it. And operations to access the value.
As Reed Copsey mentioned, this was a huge issue during .NET 1.0/1.1 since it didn't have generics; when performance was really important you had to create a typed collection. Code generators could very well be a part of your toolkit, both for performance, but also for convenience.
精彩评论