C#
programming
arrays
array manipulation
delete element

How to delete an element from an array in C

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

In C#, arrays are fixed-size, so deleting an element always means creating a new array or switching to a mutable collection type. Many bugs come from expecting in-place shrink behavior that arrays do not support. The right strategy depends on whether removal is by index, by value, one-time, or repeated frequently.

Arrays Are Fixed-Length by Design

This is the key rule: T[] length cannot change after allocation. Removal therefore requires copying selected elements into a new array.

For frequent insert and remove operations, List<T> is often a better data structure.

Remove by Index With Manual Copy

Manual copy is explicit and easy to validate.

csharp
1using System;
2
3public static class ArrayRemoval
4{
5    public static int[] RemoveAt(int[] source, int index)
6    {
7        if (source == null) throw new ArgumentNullException(nameof(source));
8        if (index < 0 || index >= source.Length)
9            throw new ArgumentOutOfRangeException(nameof(index));
10
11        int[] result = new int[source.Length - 1];
12        int write = 0;
13
14        for (int read = 0; read < source.Length; read++)
15        {
16            if (read == index) continue;
17            result[write++] = source[read];
18        }
19
20        return result;
21    }
22}
23
24int[] values = { 10, 20, 30, 40 };
25int[] updated = ArrayRemoval.RemoveAt(values, 2);
26Console.WriteLine(string.Join(",", updated));

Remove by Index With Array.Copy

Array.Copy can be faster and concise for large arrays.

csharp
1using System;
2
3public static T[] RemoveAtCopy<T>(T[] source, int index)
4{
5    if (source == null) throw new ArgumentNullException(nameof(source));
6    if (index < 0 || index >= source.Length)
7        throw new ArgumentOutOfRangeException(nameof(index));
8
9    T[] result = new T[source.Length - 1];
10
11    if (index > 0)
12        Array.Copy(source, 0, result, 0, index);
13
14    if (index < source.Length - 1)
15        Array.Copy(source, index + 1, result, index, source.Length - index - 1);
16
17    return result;
18}

This avoids per-element branch checks in the copy loop.

Remove by Value

If removal is value-based, decide whether you want first match or all matches.

Remove all matches with LINQ:

csharp
1using System;
2using System.Linq;
3
4int[] arr = { 1, 2, 3, 2, 4 };
5int[] noTwos = arr.Where(x => x != 2).ToArray();
6Console.WriteLine(string.Join(",", noTwos));

Remove first match only:

csharp
int index = Array.IndexOf(arr, 2);
if (index >= 0)
    arr = RemoveAtCopy(arr, index);

Use List<T> for Repeated Mutations

When many removals happen over time, convert to List<T>.

csharp
1using System;
2using System.Collections.Generic;
3
4List<int> list = new() { 1, 2, 3, 4, 2 };
5list.Remove(2);     // removes first matching value
6list.RemoveAt(2);   // removes by index
7
8int[] finalArray = list.ToArray();
9Console.WriteLine(string.Join(",", finalArray));

This often simplifies logic and improves code maintainability.

Remove a Range of Elements

For batch deletions, range-based copy is more efficient than repeated single removals.

csharp
1using System;
2
3public static T[] RemoveRange<T>(T[] source, int start, int count)
4{
5    if (source == null) throw new ArgumentNullException(nameof(source));
6    if (start < 0 || count < 0 || start + count > source.Length)
7        throw new ArgumentOutOfRangeException();
8
9    T[] result = new T[source.Length - count];
10    Array.Copy(source, 0, result, 0, start);
11    Array.Copy(source, start + count, result, start, source.Length - (start + count));
12    return result;
13}

Range operations matter in data-cleanup and edit-buffer workflows.

Complexity and Allocation Tradeoffs

Any array deletion is at least O(n) due to copying. Frequent deletions also create many allocations and pressure garbage collection.

Guideline:

  • Rare deletion: array copy approach is fine.
  • Frequent mutable edits: use List<T>.
  • Performance-critical hot path: benchmark copy strategy versus list workflow.

Common Pitfalls

  • Expecting array length to shrink in place. Fix: create a new array or switch to List<T>.
  • Forgetting index validation before removal. Fix: guard bounds and throw clear exceptions.
  • Using LINQ in tight loops without considering allocations. Fix: prefer manual copy in performance-sensitive paths.
  • Removing all matches when only first match should be removed. Fix: define removal contract explicitly.
  • Repeated single deletions for contiguous ranges. Fix: use one range-removal copy operation.

Summary

  • C# arrays are fixed-size, so deletion requires new allocation.
  • Remove by index with manual loop or Array.Copy.
  • Remove by value with clear first-match or all-match semantics.
  • Prefer List<T> for frequent mutable edits.
  • Choose the approach based on correctness contract and performance profile.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.