Collections

Lists

A list is the most popular collection type provided by the framework. It is a general purpose collection which can easily be extended. Here is an example:

using System; using System.Collections.G...

There are actually two forms of the List, the untyped System.Collections.List and the generic System.Collections.Generic.List<T>. We'll be dealing with the latter as its better practice to use typed collections instead of untyped. We're going to be covering this subject in much more detail in a future tutorial.

To declare a List<T> you are using a special syntax known as generics. the < and > tokens in the declaration mark generic type parameters. When we do this:

List<string> names = new List<string>();

We are saying that we want to create a new List of type string. This means that the list will only support the storing of string instances. I can also do this for other types:

List<int> ages = new List<int>();
List<DateTime> datesOfBirth = new List<DateTime>();

You can also substitute the var keyword much like any other declaration:

var droids = new List<Droid>();

You can also initialise a list and provide values:

List<int> ages = new List<int> { 1, 2, 3, 4 };

Again, like arrays, the compiler will infer set the initial capacity and add the values.

Accessing list values.

There are a few ways that a value can be obtained from a list. The list supports index notation (as seen previously with Arrays), and this is because a list itself uses an Array as a backing field. The List type is essentially a wrapper around an Array with additional methods to support easy adding, removing of items, and expansion of the underlying array.

Adding new values

To add a new value to a list, you make a call to the Add method

list.Add("my value");

Because the List<T> type becomes a typed instance (e.g., List<string> or List<int>), the Add method will only accept arguments of the same type:

List<int> ages = new List<int>();
ages.Add("hello"); // Will not compile.

You can also use the Insert method to set a value at a specific index in the array.

names.Insert(0, "Han");

Reading and replacing existing values

Building off of our understanding of the underlying array that supports the list, we use the same index-notation for accessing list values:

string name = names[0];
names[0] = "Han";

If you specify an index that does not exist, you'll get an ArgumentOutOfRangeException thrown.

Removing values.

There are two approaches to removing items from a list instance. The first is the Remove method, which accepts the value you want to remove:

names.Remove("Han");

As an alternative, you can use the RemoveAt method to remove an item as a specific index.

names.RemoveAt(0);

If you don't know the index, you can use the FindIndex to get the index of the item. If the result of this method is -1, it means the item didn't exist:

int index = names.FindIndex("Han");
if (index >= 0)
{
    names.RemoveAt(0);
}

Iterating through a list

.NET Collections support a model of iteration called enumerators. Essentially an enumerator is a type that allows you to move forward through a set, one item at a time. All of the .NET collections implement the enumerable pattern, which is exposed through a C# block statement called the foreach loop:

foreach (string name in names)
{
    Console.WriteLine(name);    
}

A foreach loop is defined as using the following syntax:

foreach (<type> <identifier> in <expression>)
    <body>

You can also use the for loop to move through the list:

for (int i = 0; i < names.Count; i++)
{
    Console.WriteLine(names[i]);   
}

You'll notice that the list exposes a Count property rather than a Length property, this is because the Length of an array is what size of array has been allocated whereas the Count of a list is how many items are stored by it. The underlying array of the list is larger than the number of items stored.

Page 6 of 31