开发者

Is there any advantage to using generic collections when you are only storing reference types?

I have been reading a book and encountered a statement, that generics allow the programmer to avoid need of boxing and unboxing when using e.g. Stack.

I think i开发者_如何学运维t is not entirely correct as the Stack (not generic) could hold just reference type variables and then there is just casting, no boxing.

EDIT: AFAIK, boxing relates to only value types to object conversion. Is that correct or am I missing something?


If you have a Stack<SomeReferenceType> no (un)boxing will occur simply because references never need to be boxed. References are the "normal" way types work in .NET - object is after all a reference type.

Edit: Your clarified question makes clear you're talking about the non-generic variant of Stack. You are correct in saying that this variant does not need to box and unbox reference types, since reference types are never boxed (and indeed cannot be boxed). It is also correct that if you place an instance of a subclass of object into the Stack, then when you take the item out and try to use an aspect of the instance (which is not general to all objects), then you will need to cast to the subclass.

Note that (for reference types) though we speak of 'casting' to object conceptually, this doesn't correspond to an actual operation; upcasting (to object or any other superclass) is free. It's in the downcast that the machine needs to verify that the downcast is valid. So merely filling a non-generic variant of Stack with instances of reference types is efficient; overhead only occurs when extracting from the Stack and casting to a more specific type.

Why you should prefer the generic collections.

Although (down)casting is fairly cheap, it's not free. Even for reference types, if you need to extract the values again, expect the generic collections to outperform their non-generic counterparts slightly. However, even when you're (as usual) not interested in a few CPU cycles, the generic collections are preferable because they help you spot bugs sooner: if you accidentally add an item of the wrong type to a non-generic list, you won't get a warning nor will you see an error until you extract and use that value, which may be much later (or even never) and in a different code file or even different assembly. Debugging such errors is a real hassle, particularly if you code has a bunch of layers and the error isn't in the layer directly accessing the collection.

By contrast, a generic collection won't even compile if you attempt to add a value of an incorrect type. And even if you need to implement a type-unsafe interface and the compiler can't catch the error, you'll still have the advantage that an InvalidCastException is thrown when you add the item to the collection (near the root cause of the bug) rather than after extraction (far from the root cause of the bug). There will be bugs in code, and you want to find them quickly and cheaply, rather than get odd exceptions in seemingly unrelated code.

Really, the only reason to ever use the non-generic collections anymore is to inter-operate with legacy API's that require their use.


The problem is that the Stack class stores the objects you put into it as object. This means, every time you put something on the stack, it will be boxed into an object and every time, you want to use on object from the stack, you need to unbox it again, to get the correct type.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜