Collections and Generics Tutorial – C#

Arrays and Collections

The .NET Framework includes a variety of different collections that you can use to organize groups of related data. These classes include ArrayList, Queue, Stack, StringCollection, and BitArray. ArrayList, Queue, and Stack can be used with any class, including custom classes. StringCollection can only be used with strings, and BitArray can only be used with Boolean values.

Dictionaries provide functionality similar to collections, but they use name/value pairs to access data. The .NET Framework provides the Hashtable, SortedList, StringDictionary, ListDictionary, HybridDictionary, and NameValueCollection dictionaries to support a variety of different data types and performance requirements.

This lesson describes the most useful Collection and Dictionary classes.

At the end of this lesson, you will be able to:

  • Use collections and choose the best collection class for different requirements
  • Use dictionaries and choose the best dictionary class for different requirements

Arrays

In C#, you declare an array by using square braces. You can define the contents of an array by using curly braces.

Once you create an array, you can access the contents of an array by specifying the element number (starting with 0) or iterate through every element in the array by using a For Each loop.

An array of a type can have different methods than the type itself. For example, an array of integers has the Average method (which returns the average of the integers in the array), the Min and Max methods (which return the lowest and highest elements), and the Sum method (which returns the total of the elements).

The Array class has a variety of static members you can use to perform different actions on elements in an array. The following code sample demonstrates using the Array.Sort method, which sorts the contents of an array if the type supports sorrting. The next topic lists other Array methods.

// Declare and initialize an array.

int[] ar = { 3, 1, 2 };

// Call a shared/static array method.

Array.Sort(ar);

// Display the result two different ways.

Console.WriteLine("{0}, {1}, {2}", ar[0], ar[1], ar[2]);

foreach (int i in ar)

    Console.WriteLine(i);

Array Methods

This table shows the most useful static methods provided by the Array class. You can use these to process arrays. Some methods, such as Sort, only work with specific types of elements. If you call Array.Sort using an array of elements that do not support the IComparable interface, the runtime will throw an exception.

Method

Description

BinarySearch

Searches an array for a value. The array must already be sorted.

Copy

Copies a range of elements to a second array, performing casting and boxing (as described in Module 1) as required.

Find

Searches for an element within an array, and returns the first occurence it finds. To find all occurences, use the FindAll method.

FindAll

Finds all elements that match the specified conditions.

Reverse

Reverses the order of the elements in an array.

Collections

The .NET Framework provides a variety of different collection classes that you can use for different circumstances. ArrayList is the most versatile, but it lacks the specialized features of the other classes.

Collection

Description

ArrayList A colleciton that dynamically grows. You can add any type to an ArrayList, including multiple types to a single instance of ArrayList.
BitArray An array of Boolean values.
Hashtable A collection of key/value pairs.
Queue A first-in, first-out collection. Queue provides the Enqueue method to add elements to the collection, the Dequeue method to remove elements from the collection, and the Peek method to access an element without removing it.
Stack A last-in, first-out collection. Stack provides the Push method to add elements to the collection, the Pop method to remove an element from the collection, and the Peek method to access an element without removing it.
SortedList A collection of key/value pairs that are sorted by the key. You can access elements by using the key.

Demonstration: Using Arrays and Collections

Watch this video about using arrays and collections in C#. Be sure to watch it full-screen in HD. You can download the source code solution for this project here: Shopping Cart Project in C#

Here’s the full transcript:

To demonstrate the use of collections, I’m going to create a console application that simulates a shopping cart.

First, let’s create a class called Item. These items will be anything that you might add to the shopping cart. I’ll give it a couple of simple properties: a title and a price.

Just to make it easier to display, let’s override the ToString method. We’ll just show the title if somebody calls ToString. Actually, let’s show both the title and the price.

Now I’ll create a constructor that defines both the title and the price.

That’s enough for my Item. Of course, we should be more specific here—if somebody is buying a book, we should have a separate class for a book because books have unique properties such as an author. If somebody is buying a CD, we should be able to define the artist.

I’m going to derive classes for both books and CDs from the Item class. The reason for doing that will be more obvious as we go along, but basically it allows us to treat both books and CDs as the same class, because we’ll be able to deal with the common base class the properties contained within the base class.

So, for the book I’ll define the ISBN, which is a code that uniquely defines the book. I’ll also give it a custom constructor that not only defines the title and price that are in the base class, but also the ISBN.

And I will quickly also define a CD based on the Item class with the unique Artist property. To do that, I’m also going to need to define a default constructor for Item.

OK, that should do it. Now I’ll be able to get into the meat of the application, which involves adding instances of books or CDs to an array, and then displaying that array or sorting that array. So, the first class I’ll work with is an ArrayList that requires me to add the System.Collections namespace.

Here, I’ll define an instance of ArrayList and I will simply go through and manually add a few different items. You’ll see this wouldn’t be efficient to do it in the real world, but for the sake of this example, it will keep it simple. To do that, I’m also going to need to define a default constructor for Item. That should do it.

Now I’ll be able to get into the meat of the application, which involves adding instances of books or CDs to an array, and then displaying that array or sorting that array. The first class I’ll work with is ArrayList. That requires me to add the System.Collections namespace. Here, I’ll define an instance of ArrayList.

I’ll simply go through and manually add a few different items. You’ll see this wouldn’t be efficient to do it in the real world, but for the sake of this example, it’ll keep it simple. We’ll just call the add method, and then create a new instance of each item. I’ll use one of my books, the Windows Vista Resource Kit, and call the book constructor which requires typing the ISBN (no, I don’t have this memorized). And the Windows 7 Resource Kit…

To demonstrate that we can add different types of objects to an ArrayList, I’m going to create a couple of CDs, too. I’m going to use the standard Microsoft fictitious names because I don’t have any CDs released.

With the Items ArrayList filled with different types of items, I’m going to create a method that simply displays them to the console. I’ll call it ShowShoppingCart. Notice that it takes an instance of ArrayList, so it doesn’t care about the contents of the ArrayList. It’s simply an instance of ArrayList.

I’ll create a for-each loop to iterate through the objects in the ArrayList. Notice that I don’t need to say “for-each-book” or “for-each-CD” in the ArrayList. I simply need to use the base class that they have in common, and I’ll be able to access the properties that are available in the base class. I’m just displaying them to the console, so a simple ToString will suffice. I’m going to add a method to the Main method to pause the console when I run it.

And, of course, I need to call the ShowShoppingCart method. This is ready to run and we’ll be able to view the contents of the shopping cart. Notice that the sequence is exactly the sequence that I ordered them in; they’re not sorted in any way. We’ll do that next.

So, ArrayList has a method called Sort that we can call. Let’s just do that and see what happens. We get an error message saying that it couldn’t compare two elements of the array. If you want to sort something, you have to implement the IComparable interface. Let’s go and do that now.

To do that, we’ll just inherit the IComparable interface. C# will make it easy for us to implement the interface. Down here, it added the structure for the method, and I just need to overwrite the default constructor. So, CompareTo is really easy to implement. All CompareTo wants to know is which of two instances comes first if you sort them. So, we could sort them by price or title. For now, let’s make the default sorting method by title.

So, we can do this all in one line. All I need to do is to access the title property and then call its default comparer. Title is a String, and String has the CompareTo method already implemented. So, I’ll call that and compare that to the object that is already compared to. I’ll let the String implementation see which of those comes first.

You can see that there’s an existing instance. The CompareTo method accepts an object class, which is an object of the same type, and I need to return whichever comes first. So, I’m calling the Title property’s implementation of CompareTo, and passing it the exact same parameter that I was passed, but cast to an Item, and then the title property of that object. It will return whichever one comes first, and then my return string passes that up to the original caller. This will be enough for the Array.Sort method to work. You can see here that Contoso music comes first because it starts with a C, followed by Fabrikam Music.

In a shopping cart, some people want to see things sorted by price. That gets a little more complicated. If you want to do something other than the default comparer, you can create your own IComparer implementation. Let’s do that now to allow people to sort things in the Items array by price.

We’ll call it SortItemsByPrice, and we want IComparer rather than IComparable. I’ll implement the standard interface here. Now, the Compare method is not an instance of the class being compared—it’s its own class. So, it actually receives two different objects. We’re returning an integer indicating which of the two comes first.

The implementation is still going to be pretty easy. First, I’m going to cast the two objects to the correct item. Then, I’m going to call the implementation from the base property class. So, for my return, I’m simply going to access Price and call the CompareTo method. I’m also going to alter one of these prices—let’s say that there’s a sale on the Windows Vista Resource Kit, so we’re going to lower the price of that.

The Sort method can take an IComparer instance, so I’ll pass it the SortItemByPrice class. First, I need to create an instance of it. Then, I can pass it.

Here it is—you can see that it correctly sorted the ArrayList by Price. So, the ArrayList class is my favorite class for general array usage. Sometimes, you need more specialized uses. Let’s say you’re creating an array that keeps track of orders different customers have placed so that you could ship them in order from first received to last received. The .NET Framework provide the Queue class to do that.

I’m going to remove my ArrayList implementation and replace it with a Queue. Otherwise, it basically works the same. Queue doesn’t have an Add method, instead it has Queue. IT does basically the same thing as Add, it just has a different name. You generally don’t sort items in a Queue, because after all, you want to work with them in the order they came in. Queue is first-in, first-out, which is perfect for shipping or serving customers. So, I need to change my ShowShoppingCart to work with a Queue instead. Generally, you wouldn’t work with a for-each loop with a Queue. Instead, what you’ll do is call the DeQueue method. So, instead of a for-each Loop, I’ll create a while loop that iterates through all the items in the Queue.

When you DeQueue something, it’s removed from the Array. So, calling DeQueue is like accessing the item and removing it at the same time. As long as there are more than one item in the Queue, we’ll keep iterating through the While loop. Here, I’ll extract the first item from the Queue and I’ll write it to the console so we can see it.

So, let’s give this a shot. As you can see, it displays the items in the exact order that I added them. The first one added was the Vista Resource Kit, so that was the first one displayed—first-in, first-out.

The .NET Framework provides another, very similar, but kind of opposite, collection type called Stack. People who have done low-level programming already know the way stacks work: they’re a last-in, first-out type of collection. Instead of calling EnQueue, you call Push. You Push things onto a stack, and you EnQueue them onto a Queue. In the development world, Stacks are used to keep track of methods that call each other. So, if Method A calls Method B and then Method B calls Method C, once Method C completes, execution needs to return to Method B, which is the last item added to the stack. After Method B completes, execution needs to return to Method (the last item added to the stack). You wouldn’t want a first-in, first-out method, because Method A wouldn’t be ready after Method C completes.

In the real world, you might use a Stack to determine which items in an inventory should be removed first. For example, if you had 50 copies of a book in your warehouse, all stacked on top of each other, and you wanted to determine which one should go out first, you would take the top one off of the stack even though it was the last one added.

As before, I need to update the ShoppingCart to work with a Stack instead. Instead of calling DeQueue, I want to call Pop—Pop removes the item from the stack. We’ll run this, and what we’ll see is the items in the exact opposite order. So here, Fabrikam was the last item added to the stack, but it’s the first item to come off. If you ever do need to view an item in the stack without removing it, you can use the Peek method. It’s the same as Pop, but it returns an item without removing it. If I were to add this now, it would just cycle forever.

Return to the .NET Framework Fundamentals Tutorials Table of Contents.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>