You didn't say what language you used before, but I feel pretty confident in saying that if you believe that array was the only thing available, then you were probably mistaken.
C++ for example only supports array "collections" natively ("collections" used very loosely here), but with the addition of pointers you can implement an equivalent for any collections data structure available in .Net. In fact, if you look in the C++ standard template library you will find stock implementations for most of the common structures.
The reason for the additional structures is that an array is not always, or even often, the most appropriate structure to use for a collection of data. It has a number of limitations that can be solved by one collection or another, and using those different collections you can often get much greater performance out of much less code, and reduce the chance there's a bug in your data structure implementation as well.
When deciding what collection type to use, you need to look at how it will be used most ofen. For example, are all the objects in the collection expected to be of the same type, inherited from the same type, or any type? Are you going to be frequently adding and removing items? If so, will you always push/pop, queue/dequeue items or do you need to add items to specific locations? Will you lookup specific items by key, by index, or both? If by key, how is the key determined?
Some of the more common collections:
List<T>
should probably be used in most of the situations where you're used to using an array. It supports lookup by index using the same syntax as an array with performance approaching that of an array, is strongly-typed, and makes it very easy to add or remove items and very fast to append or pop items (inserting to a specific position is much slower).
LinkedList<T>
should sound familiar if you've done any formal computer science training. It uses syntax similar to List, but is optimized differently: lookups are slower because they require traversing the list, while adding or removing an item to a specific position can be much faster.
Dictionary<TKey, TValue>
uses syntax similar to a List<T>
, but instead of an array index you put a key value in the brackets. Dictionaries are great because lookups of specific items by key are considered to be very fast, in that no matter how many items are in the Dictionary it will always take about the same amount of time to find the one you need.
SortedList<TKey, TValue>
works much a like a Dictionary, with the exception that when you iterate over it items are returned sorted by key. However, you can't lookup the nth item without first iterating all the items before it.
KeyedCollection
is often overlooked because it's hidden in a different namespace from some of the other collections and you have to implement a (very easy) function to use it. It also works much like a dictionary, with the addition that it supports easy lookup by index. It is normally used when the key for an item is a simple property of the item itself.
Don't forget the old standbys: Stack
and Queue
. Again, if you have any formal computer science education at all you should already have a pretty good idea how those work based on their names.
Finally, most of these collections (array included!) implement a set of common interfaces. These interfaces are very useful, in that you can write a program against an interface rather than a specific collection, and then your function can accept any collection that implements that interface. For example, the following code will work whether you pass in a string array, a List<string>
, or any other IEnumerable<string>
:
void WriteToConsole(IEnumerable<string> items)
{
foreach (string item in items)
{
Console.WriteLine(item);
}
}
Other interfaces worth looking at include IList<T>
, ICollection<T>
, and IQueryable<T>
.