Collections: Holding Many Values
By the end of this lesson
Store a group of related values and work through them, choosing between a fixed array and a growable list.
One variable holds one value. Real programs deal with groups: all the orders for today, every product in a category, each line on an invoice.
A collection holds many values under one name.
Arrays — a fixed number of slots
string[] weekdays = { "Mon", "Tue", "Wed", "Thu", "Fri" };
Console.WriteLine(weekdays[0]); // Mon
Console.WriteLine(weekdays[4]); // Fri
Console.WriteLine(weekdays.Length); // 5- Square brackets after the type mark it as an array.
- Items are reached by position, and positions start at 0 — so the first item is [0] and the fifth is [4].
- Length tells you how many items there are. The last valid position is always Length - 1.
Lists — when the size changes
An array's size is fixed when you create it. That is fine for days of the week and useless for a shopping basket, where you do not know how many items there will be.
List<string> basket = new List<string>();
basket.Add("Notebook");
basket.Add("Pen");
basket.Add("Desk lamp");
Console.WriteLine(basket.Count); // 3
basket.Remove("Pen");
Console.WriteLine(basket.Count); // 2
foreach (string item in basket)
{
Console.WriteLine(item);
}- List<string> means a list of strings. The angle brackets say what it holds.
- Add appends an item and Remove takes one out, so the size changes as the program runs.
- Count is the list equivalent of an array's Length.
Choosing between them:
| Array | List | |
|---|---|---|
| Size | Fixed when created | Grows and shrinks |
| Add or remove items | Not possible | Add, Insert, Remove |
| How many items | Length | Count |
| Use when | The set is known and will not change | Items are collected as the program runs |
In practice you will use List far more often than arrays, because most real collections are built up rather than known in advance.
Combining with what you already know
List<decimal> orderTotals = new List<decimal> { 24.99m, 150.00m, 8.50m, 620.00m };
decimal largeOrderThreshold = 100m;
int largeOrders = 0;
decimal revenue = 0m;
foreach (decimal total in orderTotals)
{
revenue += total;
if (total >= largeOrderThreshold)
{
largeOrders++;
}
}
Console.WriteLine($"Revenue: {revenue}, large orders: {largeOrders}");Summary
- A collection holds many values under one name
- Array size is fixed; List grows and shrinks as the program runs
- Positions start at 0, so the last is Length - 1 or Count - 1
- Do not modify a collection while looping over it with foreach
- An empty collection is a normal case that calculations must handle
Practice
Attempt each one before opening the solution. Getting it wrong first is how the idea sticks.
Try it yourself
Try it yourself
Build a list of five product names. Print each with its position number starting from 1 (not 0), so it reads as a numbered list for a human.
Show solution
Use a for loop when you need the index. Print i + 1 so the display starts at 1 while the list access still uses the real position.
This gap between internal positions and human-facing numbering appears constantly, in pagination especially.
List<string> products = new List<string>
{
"Notebook", "Pen", "Desk lamp", "Monitor stand", "Cable tidy"
};
for (int i = 0; i < products.Count; i++)
{
Console.WriteLine($"{i + 1}. {products[i]}");
}Challenge
Challenge
Given a list of order totals, find the largest one without using any built-in maximum method.
Think about what the starting value of your "largest so far" variable should be, and what should happen if the list is empty.
Show solution
Starting from zero looks reasonable but breaks if every value is negative. Starting from the first item is safer, which means handling the empty list separately.
That empty case is the interesting part of this exercise. There is no sensible "largest" value for an empty list, so the honest options are to refuse or to signal that no answer exists.
List<decimal> totals = new List<decimal> { 24.99m, 150.00m, 8.50m, 620.00m };
if (totals.Count == 0)
{
Console.WriteLine("No orders to compare.");
}
else
{
decimal largest = totals[0];
foreach (decimal total in totals)
{
if (total > largest)
{
largest = total;
}
}
Console.WriteLine($"Largest order: {largest}");
}Knowledge check
Nothing is recorded and there is no score. The explanation appears either way.
Saved in this browser only.