Start learning free

LESSON 94 OF 347 · ARRAYS I

List Size in C#: Count and the Last Element

Lesson Read the full explanation

We can get the size of an List using the .Count method:

List<int> ourArray = new List<>(List.of(50, 40, 30));

// Printing the size:
Console.WriteLine(ourArray.Count); // Output: 3

// Changing the List:
ourArray.Remove(2);

// Printing the new size:
Console.WriteLine(ourArray.Count); // Output: 2

Using the size

We can use the size to access items from the end of an ArrayList.

Because ArrayLists are 0-indexed, the index of the last item is size - 1:

List<int> ourArray = new List<>(List.of(50, 40, 30));

int size = ourArray.Count;

// Printing the last item:
Console.WriteLine(ourArray.get(size - 1)); // Output: 30

// Printing the second to last item:
Console.WriteLine(ourArray.get(size - 2)); // Output: 40

Assignment
Follow the Coding Tutorial and let's play with some arrays.


Hint
Look at the examples above if you get stuck.


STEP 1 OF 3
    Ctrl + Enter to check

    C# · ARRAYS I

    Array Length in C#, explained

    Count, not Length

    A List<T> reports how many items it holds with the Count property. Arrays use Length for the same idea, so keep the two names apart.

    List<int> ourArray = new List<int> {50, 40, 30};
    
    Console.WriteLine(ourArray.Count);  // 3
    

    Unlike an array's length, a list's count changes as the list does. Adding an item increases it, and removing one decreases it:

    ourArray.Add(20);
    Console.WriteLine(ourArray.Count);  // 4
    
    ourArray.RemoveAt(0);
    Console.WriteLine(ourArray.Count);  // 3
    

    RemoveAt takes an index. A different method, Remove, takes a value and removes the first matching item. For a List<int> holding 50, 40, 30, the call Remove(2) looks for the number 2, finds nothing, returns false and leaves the list unchanged.

    Using the count to reach the end

    Indexes start at 0, so the last item is at index Count - 1 and the one before it is at Count - 2:

    List<int> ourArray = new List<int> {50, 40, 30};
    int size = ourArray.Count;
    
    Console.WriteLine(ourArray[size - 1]);  // 30
    Console.WriteLine(ourArray[size - 2]);  // 40
    

    Items are read with the square-bracket indexer. C# lists have no get method and no size() method.

    Count in loops

    The most common use of Count is as the limit of a loop over the list. The last index is Count - 1, so the loop continues while the index is less than the count:

    List<int> ages = new List<int> {14, 32, 50, 21};
    int total = 0;
    
    for (int i = 0; i < ages.Count; i++) {
        total += ages[i];
    }
    Console.WriteLine(total);  // 117
    

    Count is not capacity

    A list keeps its items in an array that it replaces with a bigger one when it fills up. The list's Capacity is the size of that internal array, and it can be larger than the number of items. Count is the number of items actually stored, and it is the value to use for indexing and loops. A list with no items has a count of 0 whatever its capacity.

    The exercise, step by step

    The starter code declares fruits, a list of three strings, and ages, a list of four ints.

    1. Print the number of fruits. fruits.Count is 3.
    2. Print the last age. The last index is ages.Count - 1, which is 3, so this prints 21.
    3. Print the second to last age. Subtract 2 instead: ages.Count - 2 is index 2, which holds 50.
    List<string> fruits = new List<string>(new[] {"mango", "kiwi", "grapefruit"});
    List<int> ages = new List<int>(new[] {14, 32, 50, 21});
    
    Console.WriteLine(fruits.Count);
    Console.WriteLine(ages[ages.Count - 1]);
    Console.WriteLine(ages[ages.Count - 2]);
    

    The output is:

    3
    21
    50
    

    Common mistakes

    • Using Length on a list. ages.Length doesn't compile, because lists have Count. The reverse is also true: arrays have no Count property.
    • Using Count as the last index. ages[ages.Count] is one past the end and throws an ArgumentOutOfRangeException.
    • Calling it like a method. ages.Count() is not what you want here. Count is a property, so write it without parentheses.
    • Empty lists. A list with no items has a count of 0, so list[list.Count - 1] asks for index -1 and throws. Check the count first.
    • Confusing Remove and RemoveAt. One works on values, the other on positions.

    Comparing with arrays

    An array keeps one fixed size for its whole life, so its Length only reflects the size chosen at creation. A list's Count follows its contents. That is why list code usually reads Count at the moment it needs it, in the loop condition or in the index expression, rather than saving the value early. A saved value can become stale after an Add or a RemoveAt.

    The same care applies in the other direction. If a loop removes items while it counts upwards, the list gets shorter under the loop's feet and items can be skipped. Looping backwards from Count - 1 down to 0 avoids that problem when you need to remove items as you go.

    Things to try

    Add an item to ages with ages.Add(1) and print ages.Count and then ages[ages.Count - 1]. The count becomes 5 and the last item is 1. The expression ages.Count - 1 always points at the newest item, whatever the list's size. Compare this with an array, whose length can never change.

    Key takeaways

    • list.Count is the number of items, and it changes as items are added or removed.
    • The last valid index is Count - 1.
    • Arrays use Length; lists use Count.
    Keep going with C#About 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free