Intro
So some of you who have been following this series since the beginning may remember in previous chapters, (Loops) we looped over a list of addresses using a List<AddressBook>
object. But we haven't really dove into how you collections are instantiated (created) or what kinds there are in much depth. Therefore the next couple of chapters, will be dedicated to doing just that.
What kinds of collections does C# offer ?
There are different types of collections in C#, but these fall in predominantly 2 (two) categories, Generic and Non-Generic.
Generic Collections - A generic collection is strongly typed (you can store one type of objects into it) so that we can eliminate runtime type mismatches e.g:
var phoneNumbers = new List<int>();
//or
var boysNames = new List<string>();
//or
var animals = new List<Animal>();
This is most common form of collection.
Non-Generic Collections - A non-generic collection is not strongly typed (you can store more than one type of object into it). These types of objects tend to be slower in performance,
e.g they could hold an Address
object, a bool
value and a Person
object all the same array.
Why are generic collections called generic when they're very specific in what they hold?
I've been asked this question before, and until you forget about English definition, and think of the word generic in more programming terms it won't make much sense.
We'll touch on Generics* in C# a bit more in future chapters, but, generics in C# just really means that the object you're creating can be of any type.
If you take a look at the List
type, the documentation shows that the declaration is List<T>
, what is the T for ? This is a placeholder to let the code know that this object can hold any type of object, and it will be declared at time of instantiation, like we did
var addressBook = new List<AddressBook>();
so we replaced the T
with the type of objects we want the list to hold. This is why these collection types are classed as Generic collections, because they utilise c# generics under the sheets to function not to be confused with they're strongly typed so must be non-generic. Generics means your specifying the type of this collection.
Generic vs Non-Generic Collections
Generic collections are the most popular, and the one you'll most likely come into contact with[. This is mainly because they are more performant, due to the compiler not having to perform boxing and unboxing (you can read more about that here). Non-generic clases hold Objects
not types of objects, hence why you can put anything you want in them, the downside is it has to convert the Object
to the type of the value at the index within the collection.
I'd advise to never use Non-Generic collections, and always aim for Generic collections, not only for the ease of readability but they're much more performant for the reasons above, and it keeps your code strongly typed.
Generic Collections
- List
- Array
- Dictionary
- Stack
- Hashset
Non-Generic Collections (Advised to never use them imo -- they're old objects from .Net 1.1, and no need for them really in .Net 2.2+)
- ArrayList
- SortedList
- Stack
- Queue
- HashTable
- BitArray
I'd replace an ArrayList and SortedList with a List, a Stack and Queue with Stack, Queue, and I don't see the need for a HashTable now we have Dictionary. With the advantages of generic collections, imo the non-generic collections have become obsolete, and the performance hit of using non-generic collections, just cements that.
Special Mention
Array - we can also use Arrays in C# however arrays aren't like collections in that they are of fixed size. When we instantiate an array we specify the size of the array upfront. Meaning we can't add to it at a later date (unlike a generic / non-generic collection). Arrays like generic collections are strongly typed and can only hold one type of object in them.
Summary
Ok, so now I'm hoping you've got a better understanding of collections, lets take a look at Generic Collections in a little more depth.