Skip to main content
C# Fundamentals for Beginners to Advanced
CHAPTER 09 Beginner

Arrays and Collections in C#

Updated: May 17, 2026
5 min read

# CHAPTER 9

Arrays and Collections

1. Introduction

If you are building a school portal, you don't want to create 100 separate variables (student1, student2, student3) for a class. You need a way to group related data under a single variable name. Arrays and Collections provide the structure to hold multiple items in memory efficiently.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Create, initialize, and access Arrays.
  • Understand the limitations of Arrays.
  • Use List<T> for dynamic data storage.
  • Explain the difference between ArrayList and List<T>.
  • Traverse collections using loops.

3. Arrays (Fixed Size)

An array is a collection of variables of the *same data type*. However, the size of an array is fixed when it is created. You cannot add more elements to it later.

Declaration and Initialization:

csharp
123456789101112
// Method 1: Specify size, then add values using the Index
string[] cars = new string[3]; // Creates an array for 3 strings
cars[0] = "Volvo";  // Arrays are zero-indexed!
cars[1] = "BMW";
cars[2] = "Ford";
// cars[3] = "Mazda"; // ERROR: Index out of bounds!

// Method 2: Initialize directly
int[] scores = { 95, 80, 100, 75 };

Console.WriteLine(scores[0]); // Prints 95
Console.WriteLine(scores.Length); // Prints 4 (Total elements)

4. Dynamic Collections: List<T>

Because arrays cannot grow or shrink, C# provides the Generic Collection List<T>. A List automatically resizes itself under the hood when you add or remove items. This is what you will use 95% of the time in modern C#.

*(Requires using System.Collections.Generic;)*

csharp
12345678910111213141516171819202122
using System;
using System.Collections.Generic;

namespace CollectionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> users = new List<string>();

            users.Add("Alice"); // Size becomes 1
            users.Add("Bob");   // Size becomes 2
            users.Add("Charlie");

            users.Remove("Bob"); // "Charlie" shifts down to take Bob's spot

            Console.WriteLine(users[1]); // Prints "Charlie"
            Console.WriteLine(users.Count); // Prints 2
        }
    }
}

5. ArrayList (The Old Way - Avoid)

Before C# 2.0 introduced Generics (<T>), developers used ArrayList. An ArrayList can hold *any* data type simultaneously (int, string, bool all mixed together). This causes major performance issues ("Boxing/Unboxing") and runtime crashes. Do not use ArrayList in modern C#. Always use List<T>.

6. Traversing Collections

You can read every item in an Array or List using loops. The foreach loop is the safest and cleanest way.
csharp
12345678910111213
List<int> numbers = new List<int> { 10, 20, 30, 40 };

// Using for loop
for (int i = 0; i < numbers.Count; i++) 
{
    Console.WriteLine(numbers[i]);
}

// Using foreach loop (Preferred)
foreach (int num in numbers) 
{
    Console.WriteLine(num);
}

7. Mini Project: Student Marks Manager

csharp
1234567891011121314151617181920212223242526272829303132
using System;
using System.Collections.Generic;

namespace MarksManager
{
    class Program
    {
        static void Main(string[] args)
        {
            List<int> marks = new List<int>();
            
            while (true)
            {
                Console.Write("Enter a mark (or -1 to finish): ");
                int input = int.Parse(Console.ReadLine());
                
                if (input == -1) break;
                
                marks.Add(input);
            }

            int sum = 0;
            foreach (int mark in marks)
            {
                sum += mark;
            }

            Console.WriteLine($"\nTotal Marks: {sum}");
            Console.WriteLine($"Average: {(double)sum / marks.Count}");
        }
    }
}

8. OOP and Memory Explanation

Both Arrays and Lists are Reference Types. They are created on the Heap. When you write int[] scores = new int[3];, the CLR allocates one continuous block of memory on the Heap large enough to hold 3 integers, and the variable scores on the Stack holds the memory address pointing to the start of that block.

9. Common Mistakes

  • IndexOutOfRangeException: Remembering that arrays and lists start at Index 0. If an array has 5 items, asking for array[5] will crash the program. The last item is array[4].
  • Using .Length vs .Count: Arrays use the property .Length. Collections like List<T> use the property .Count.

10. Best Practices

  • Default to using List<T> for data storage. Only use raw arrays if you are strictly optimizing for memory or performance in algorithms or game engines.

11. Exercises

  1. 1. Create an array of 5 integers. Write a for loop that prints them in reverse order.
  1. 2. Create a List<string> for groceries. Add 3 items, remove 1 item, and print the remaining items using a foreach loop.

12. MCQs with Answers

Question 1

What is the main limitation of standard Arrays in C#?

Question 2

At what index does a C# array begin?

Question 3

Which of the following is the modern, dynamic alternative to Arrays?

Question 4

What method is used to insert an item into a List<T>?

Question 5

Why is ArrayList considered bad practice in modern C#?

Question 6

If int[] nums = new int[3];, what happens if you call nums[3]?

Question 7

How do you find the total number of elements in an Array?

Question 8

How do you find the total number of elements in a List<T>?

Question 9

Which loop is highly recommended for reading all data in a List?

Question 10

Are Arrays Value Types or Reference Types?

13. Interview Questions

  • Q: Explain the structural difference between an Array and a List<T> under the hood. (Answer: List<T> is actually just a wrapper around an Array. When the internal array fills up, it creates a new, larger array, copies the data over, and deletes the old one).
  • Q: What is Boxing and Unboxing, and why makes ArrayList inefficient?

14. Summary

Arrays group data of the same type into a fixed-size block of memory. Modern C# relies heavily on List<T>, a dynamic generic collection that grows and shrinks automatically. The foreach loop is the standard tool for iterating through these collections safely.

15. Next Chapter Recommendation

In Chapter 10: Strings in C#, we will dive deeply into text manipulation, learning how to search, split, and optimize strings using the StringBuilder class.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·