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.