C#
arrays
value search
programming tutorial
beginner guide

Check if a value is in an array C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Checking whether an array contains a value is a basic operation, but the best method depends on what else you need from the search. In C#, the most common options are Array.Exists, Array.IndexOf, LINQ Contains, and a manual loop. All of them are valid, but they differ in readability, allocation behavior, and how much control they give you.

Use the Simplest API That Matches the Job

If you just want a yes or no answer, LINQ Contains is usually the clearest:

csharp
1using System;
2using System.Linq;
3
4int[] numbers = { 10, 20, 30, 40 };
5
6bool hasThirty = numbers.Contains(30);
7Console.WriteLine(hasThirty);

This reads well and is fine for everyday code. For arrays of primitive types, it is also plenty fast for most applications.

If you prefer a framework method that does not read like a query, Array.Exists is another good fit:

csharp
1using System;
2
3int[] numbers = { 10, 20, 30, 40 };
4
5bool hasThirty = Array.Exists(numbers, n => n == 30);
6Console.WriteLine(hasThirty);

Use this pattern when the check is more complex than direct equality.

Get the Index When Position Matters

Sometimes presence is not enough. If you also need the element position, use Array.IndexOf:

csharp
1using System;
2
3string[] names = { "alice", "bob", "charlie" };
4
5int index = Array.IndexOf(names, "bob");
6
7if (index >= 0)
8{
9    Console.WriteLine($"Found at index {index}");
10}
11else
12{
13    Console.WriteLine("Not found");
14}

This is better than calling Contains and then searching again. One pass is enough.

For custom comparison rules such as case-insensitive matching, a manual loop gives you direct control:

csharp
1using System;
2
3string[] names = { "Alice", "Bob", "Charlie" };
4string target = "alice";
5bool found = false;
6
7foreach (string name in names)
8{
9    if (string.Equals(name, target, StringComparison.OrdinalIgnoreCase))
10    {
11        found = true;
12        break;
13    }
14}
15
16Console.WriteLine(found);

Know When an Array Is the Wrong Data Structure

If you need to perform many repeated membership checks, an array may be the wrong tool. Arrays require linear search, which is O(n) per lookup. A HashSet<T> is usually better for repeated existence checks:

csharp
1using System;
2using System.Collections.Generic;
3
4int[] source = { 10, 20, 30, 40, 50 };
5var set = new HashSet<int>(source);
6
7Console.WriteLine(set.Contains(30));
8Console.WriteLine(set.Contains(99));

There is a tradeoff: creating the set has an upfront cost. For one lookup, stick with the array. For thousands of lookups, move to a set.

Equality Rules Matter for Reference Types

For arrays of custom objects, "contains" depends on equality semantics. If your type does not implement value equality, two logically equal objects may still compare as different references.

csharp
1using System;
2using System.Linq;
3
4public record User(int Id, string Name);
5
6User[] users =
7{
8    new User(1, "Alice"),
9    new User(2, "Bob")
10};
11
12bool hasBob = users.Contains(new User(2, "Bob"));
13Console.WriteLine(hasBob);

This works because record provides value-based equality. If User were a plain class without equality overrides, the result would be false.

That is why membership checks on object arrays should be reviewed together with the type design, not in isolation.

Prefer Readability Over Cleverness

A manual loop is always available:

csharp
1using System;
2
3int[] numbers = { 1, 2, 3, 4 };
4bool found = false;
5
6for (int i = 0; i < numbers.Length; i++)
7{
8    if (numbers[i] == 3)
9    {
10        found = true;
11        break;
12    }
13}
14
15Console.WriteLine(found);

This is useful when you need early exit plus extra logic such as logging, counting, or custom comparisons. But if the check is simple, Contains or Array.IndexOf is more readable and easier to review.

Common Pitfalls

  • Using Contains and then performing a second search when Array.IndexOf would give both presence and position.
  • Forgetting that object-array membership depends on equality semantics, not just visible property values.
  • Building a HashSet<T> for a single lookup and paying unnecessary setup cost.
  • Writing a long manual loop for a simple equality check that Contains already expresses clearly.
  • Assuming array membership checks are cheap even when repeated many times in hot code paths.

Summary

  • Use Contains for the clearest yes-or-no membership check.
  • Use Array.IndexOf when you also need the position.
  • Use Array.Exists or a manual loop for more complex predicates.
  • Move to HashSet<T> when membership checks are frequent and performance matters.
  • For object arrays, always confirm that equality behavior matches the search you intend.

Course illustration
Course illustration

All Rights Reserved.