← Back to C# series
📚
Collections & LINQ
Collections · Prerequisite: OOP

11. Array

An array is the most basic collection — fixed-size storage of same-typed elements in a row. Cover 1-D, multi-dim, jagged arrays, the static Array methods, and foreach usage.

C#.NET 8collectionsarray
Duration
~1-1.5 hours
Level
📊 Intermediate
Prerequisite
🎯 OOP completed
OUTCOME
An array is the most basic collection — fixed-size storage of same-typed elements in a row. Cover 1-D, multi-dim, jagged arrays, the static Array methods, and foreach usage.

What you'll learn

  • 1Declare and initialize 1-D arrays and access by index
  • 2Build a 2-D array (`int[,]`) and get its dimensions with `GetLength`
  • 3Use static methods like `Array.Sort`, `IndexOf`, `Reverse`, `Copy`
  • 4Get a one-sentence intuition for `Span<T>` / `ReadOnlySpan<T>` and why it exists

Overview

An array is the most basic data structure that stores values of the same type in a row at a **fixed size**. C# supports 1-D and 2-D arrays, and you can do many operations efficiently with the `Array` class's static methods or modern tools like `Span<T>`.

Core Concepts

1) Array declaration and collection expressions

In .NET 8 you can initialize concisely with **collection expressions** `[...]`.

csharp
int[] a = [1, 2, 3, 4, 5];   // collection expression (.NET 8+)
int[] b = { 1, 2, 3 };       // traditional form
int[] c = new int[5];        // length-5 array, zero-filled
  • Indices are **0-based**; the last index is `Length - 1`.
  • `^1` is the first from the end (= `Length - 1`).

2) 2-D array

csharp
int[,] grid = new int[3, 4];          // 3 rows, 4 cols
grid[1, 2] = 99;
int rows = grid.GetLength(0);          // 3
int cols = grid.GetLength(1);          // 4

`int[][]` is a **jagged array** where rows can have different lengths. `int[,]` is rectangular.

3) Static `Array` methods

MethodDescription
`Array.Sort(arr)`Sort ascending (in place)
`Array.Reverse(arr)`Reverse order
`Array.IndexOf(arr, value)`Index of first match, `-1` if missing
`Array.Copy(src, dst, length)`Copy the first `length` elements

4) `Span<T>` / `Memory<T>` intro

`Span<T>` is a thin wrapper that **points to a slice of an array/string without copying**. Saves memory and time since it avoids a new allocation.

csharp
ReadOnlySpan<char> slice = "hello".AsSpan(1, 3);   // "ell"

For now, just remember "efficient slicing." Advanced usage is left for a later topic.

Examples

Example 1 — `ArrayBasics`: 1-D array basics

csharp
int[] scores = [85, 92, 78, 90, 88];

Console.WriteLine($"Length: {scores.Length}");
Console.WriteLine($"First: {scores[0]}");
Console.WriteLine($"Last: {scores[^1]}");

int sum = 0;
foreach (int s in scores)
{
    sum += s;
}
Console.WriteLine($"Sum: {sum}");

**Output**

text
Length: 5
First: 85
Last: 88
Sum: 433

**Note:** `^1` is "1st from the end" — the index-from-end operator introduced in C# 8.

Example 2 — `Array2D`: working with 2-D arrays

csharp
int[,] grid = new int[3, 4];

for (int r = 0; r < grid.GetLength(0); r++)
{
    for (int c = 0; c < grid.GetLength(1); c++)
    {
        grid[r, c] = r * 10 + c;
    }
}

for (int r = 0; r < grid.GetLength(0); r++)
{
    for (int c = 0; c < grid.GetLength(1); c++)
    {
        Console.Write($"{grid[r, c],3} ");
    }
    Console.WriteLine();
}

**Output**

text
  0   1   2   3
 10  11  12  13
 20  21  22  23

**Note:** `GetLength(0)` is the row count, `GetLength(1)` the column count. `{value,3}` is a 3-wide right-aligned format.

Example 3 — `ArrayMethods`: static `Array` methods

csharp
int[] nums = [4, 2, 9, 1, 7];

Array.Sort(nums);
Console.WriteLine($"Sorted: [{string.Join(", ", nums)}]");

Array.Reverse(nums);
Console.WriteLine($"Reversed: [{string.Join(", ", nums)}]");

int idx = Array.IndexOf(nums, 7);
Console.WriteLine($"Index of 7: {idx}");

int[] copy = new int[3];
Array.Copy(nums, copy, 3);
Console.WriteLine($"First 3 copied: [{string.Join(", ", copy)}]");

**Output**

text
Sorted: [1, 2, 4, 7, 9]
Reversed: [9, 7, 4, 2, 1]
Index of 7: 1
First 3 copied: [9, 7, 4]

**Note:** `Array.Sort` mutates the **original in place** (returns nothing). Use `string.Join` to pretty-print an array.

Example 4 — `SpanIntro`: slicing with `ReadOnlySpan<char>`

csharp
ReadOnlySpan<char> text = "Hello, World!".AsSpan();

ReadOnlySpan<char> hello = text.Slice(0, 5);
ReadOnlySpan<char> world = text.Slice(7, 5);

Console.WriteLine(hello.ToString());
Console.WriteLine(world.ToString());

// Unlike Substring, no new string is allocated — it points into the source.
Console.WriteLine($"Source length: {text.Length}, slice length: {hello.Length}");

**Output**

text
Hello
World
Source length: 13, slice length: 5

**Note:** `string.Substring` allocates a new string every time; `Span` shares memory. Useful in heavy text parsing.

Full example code (src/)

src/Array2D/Array2D.csproj

xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <RootNamespace>CodingNow.Lecture.Coll11</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

src/Array2D/Program.cs

csharp
#nullable enable

// 3-row, 4-col rectangular array
int[,] grid = new int[3, 4];

for (int r = 0; r < grid.GetLength(0); r++)
{
    for (int c = 0; c < grid.GetLength(1); c++)
    {
        grid[r, c] = r * 10 + c;
    }
}

// Print as a table
for (int r = 0; r < grid.GetLength(0); r++)
{
    for (int c = 0; c < grid.GetLength(1); c++)
    {
        Console.Write($"{grid[r, c],3} ");
    }
    Console.WriteLine();
}

src/ArrayBasics/ArrayBasics.csproj

xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <RootNamespace>CodingNow.Lecture.Coll11</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

src/ArrayBasics/Program.cs

csharp
#nullable enable

// Build an array with a collection expression (.NET 8+)
int[] scores = [85, 92, 78, 90, 88];

Console.WriteLine($"Length: {scores.Length}");
Console.WriteLine($"First: {scores[0]}");
Console.WriteLine($"Last: {scores[^1]}");   // 1st from the end

int sum = 0;
foreach (int s in scores)
{
    sum += s;
}
Console.WriteLine($"Sum: {sum}");

src/ArrayMethods/ArrayMethods.csproj

xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <RootNamespace>CodingNow.Lecture.Coll11</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

src/ArrayMethods/Program.cs

csharp
#nullable enable

int[] nums = [4, 2, 9, 1, 7];

Array.Sort(nums);                  // in-place sort
Console.WriteLine($"Sorted: [{string.Join(", ", nums)}]");

Array.Reverse(nums);               // reverse order
Console.WriteLine($"Reversed: [{string.Join(", ", nums)}]");

int idx = Array.IndexOf(nums, 7);  // index of value
Console.WriteLine($"Index of 7: {idx}");

int[] copy = new int[3];
Array.Copy(nums, copy, 3);         // copy first 3
Console.WriteLine($"First 3 copied: [{string.Join(", ", copy)}]");

src/SpanIntro/Program.cs

csharp
#nullable enable

ReadOnlySpan<char> text = "Hello, World!".AsSpan();

// Point to a portion of the source without creating a new string
ReadOnlySpan<char> hello = text.Slice(0, 5);
ReadOnlySpan<char> world = text.Slice(7, 5);

Console.WriteLine(hello.ToString());
Console.WriteLine(world.ToString());

Console.WriteLine($"Source length: {text.Length}, slice length: {hello.Length}");

src/SpanIntro/SpanIntro.csproj

xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <RootNamespace>CodingNow.Lecture.Coll11</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

Common Mistakes

  1. Accessing the last+1 index like `arr[arr.Length]` → `IndexOutOfRangeException`.
  2. Accessing a 2-D array as `grid[1][2]` — for `int[,]` it's `grid[1, 2]`. (`grid[1][2]` is for `int[][]`.)
  3. Thinking `Array.Sort` returns a new array — it **mutates the original** (returns `void`).
  4. `int[]` size is fixed once set — for variable length, use `List<T>` from the next lecture.
  5. `Span<T>` can't cross an `await` in an async method — its usage has limits.

Summary

  • Arrays are **same-type, fixed-length** data structures; the collection expression `[1, 2, 3]` makes them concise.
  • 2-D arrays use `int[,]` with `GetLength(0/1)` for dimensions.
  • Common operations live as `Array` static methods (`Sort`, `IndexOf`, `Reverse`, `Copy`).
  • `Span<T>` is the modern tool for slicing without copying.

Practice

**Practice - 11. Array**

Problem 1 — max / min / average

  • Project folder: `Homework01/`
  • Key concepts: 1-D array, `foreach`, accumulation

Requirements

  • Use `int[] data = [42, 17, 89, 23, 65, 8, 50];`.
  • Iterate to compute and print **max, min, average** by hand. (`Math.Max` / `Math.Min` are fine.)
  • Print the average to one decimal (`F1`).

Expected output

text
Array: [42, 17, 89, 23, 65, 8, 50]
Max: 89
Min: 8
Average: 42.0

Hints

  • Seed with `data[0]` and compare from index 1 — that's cleanest.
  • Average is `(double)sum / data.Length` — cast to `double` to avoid integer division.

---

Problem 2 — 2-D matrix transpose

  • Project folder: `Homework02/`
  • Key concepts: `int[,]`, `GetLength`, nested for loops

Requirements

  • Create the 2x3 matrix below.

``` 1 2 3 4 5 6 ```

  • **Transpose** it into a 3x2 matrix and print it.
  • Print both the original and the transposed result as tables.

Expected output

text
Original (2x3):
1 2 3
4 5 6

Transposed (3x2):
1 4
2 5
3 6

Hints

  • Build the transposed array as `new int[orig.GetLength(1), orig.GetLength(0)]`.
  • The key one-liner is `transposed[c, r] = original[r, c];`.

Check your answer

Try it yourself, then compare against the [`answer/`](./answer/) folder.

Answer (answer/)

homework/answer/Homework01/Homework01.csproj

xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <RootNamespace>CodingNow.Lecture.Coll11</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

homework/answer/Homework01/Program.cs

csharp
#nullable enable

int[] data = [42, 17, 89, 23, 65, 8, 50];

int max = data[0];
int min = data[0];
int sum = 0;

foreach (int n in data)
{
    max = Math.Max(max, n);
    min = Math.Min(min, n);
    sum += n;
}

double avg = (double)sum / data.Length;

Console.WriteLine($"Array: [{string.Join(", ", data)}]");
Console.WriteLine($"Max: {max}");
Console.WriteLine($"Min: {min}");
Console.WriteLine($"Average: {avg:F1}");

homework/answer/Homework02/Homework02.csproj

xml
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <RootNamespace>CodingNow.Lecture.Coll11</RootNamespace>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

homework/answer/Homework02/Program.cs

csharp
#nullable enable

int[,] original = { { 1, 2, 3 }, { 4, 5, 6 } };

int rows = original.GetLength(0);
int cols = original.GetLength(1);

int[,] transposed = new int[cols, rows];
for (int r = 0; r < rows; r++)
{
    for (int c = 0; c < cols; c++)
    {
        transposed[c, r] = original[r, c];
    }
}

Print("Original (2x3):", original);
Console.WriteLine();
Print("Transposed (3x2):", transposed);

static void Print(string title, int[,] m)
{
    Console.WriteLine(title);
    for (int r = 0; r < m.GetLength(0); r++)
    {
        for (int c = 0; c < m.GetLength(1); c++)
        {
            Console.Write($"{m[r, c]} ");
        }
        Console.WriteLine();
    }
}

Try It Yourself

bash
cd src/ArrayBasics
dotnet run

cd ../Array2D
dotnet run

cd ../ArrayMethods
dotnet run

cd ../SpanIntro
dotnet run

Next Lecture

[12_List_Dictionary_HashSet](../12_List_Dictionary_HashSet/) — Variable-length collections and key-value stores.

Example code / lecture materials

All lecture materials and example code are openly available on GitHub.

View on GitHub ↗