C#
.NET
IEnumerable
FirstElement
ProgrammingTips

How do I get the first element from an IEnumerableT in .net?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

The most common way to get the first element from an IEnumerable<T> in .NET is First() (throws if empty) or FirstOrDefault() (returns default(T) if empty). Both are LINQ extension methods in System.Linq. For performance-critical code with lists, list[0] is fastest but only works with IList<T>. Use FirstOrDefault() as the safe default and First() only when you are certain the collection is non-empty. For nullable reference types in C# 8+, be aware that FirstOrDefault() returns null for empty collections of reference types.

First() — Throws on Empty

csharp
1using System.Linq;
2
3var numbers = new List<int> { 10, 20, 30 };
4
5int first = numbers.First();
6Console.WriteLine(first);  // 10
7
8// With a predicate — first element matching a condition
9int firstEven = numbers.First(n => n > 15);
10Console.WriteLine(firstEven);  // 20
11
12// Throws InvalidOperationException on empty collection
13var empty = new List<int>();
14int boom = empty.First();  // InvalidOperationException: Sequence contains no elements

Use First() when you expect the collection to always have at least one element. The exception acts as a fail-fast assertion — if the collection is unexpectedly empty, you want to know immediately.

FirstOrDefault() — Returns Default on Empty

csharp
1using System.Linq;
2
3var numbers = new List<int> { 10, 20, 30 };
4
5int first = numbers.FirstOrDefault();
6Console.WriteLine(first);  // 10
7
8// Empty collection returns default value
9var empty = new List<int>();
10int result = empty.FirstOrDefault();
11Console.WriteLine(result);  // 0 (default for int)
12
13// Reference types return null
14var emptyStrings = new List<string>();
15string? s = emptyStrings.FirstOrDefault();
16Console.WriteLine(s == null);  // True
17
18// With a predicate
19int found = numbers.FirstOrDefault(n => n > 100);
20Console.WriteLine(found);  // 0 (no match found)

FirstOrDefault() is the safe choice when the collection might be empty. For value types, it returns the type's default (0 for int, false for bool). For reference types, it returns null.

FirstOrDefault with Custom Default (.NET 6+)

csharp
1// .NET 6+ overload: specify the default value
2var empty = new List<int>();
3
4int result = empty.FirstOrDefault(-1);
5Console.WriteLine(result);  // -1 (custom default instead of 0)
6
7// With predicate and custom default
8var numbers = new List<int> { 1, 2, 3 };
9int found = numbers.FirstOrDefault(n => n > 10, -1);
10Console.WriteLine(found);  // -1

The .NET 6+ overload lets you specify a fallback value, avoiding the ambiguity of 0 or null as "not found."

ElementAt() and ElementAtOrDefault()

csharp
1using System.Linq;
2
3var items = new List<string> { "a", "b", "c" };
4
5// Get element at a specific index
6string first = items.ElementAt(0);       // "a"
7string second = items.ElementAt(1);      // "b"
8
9// Safe version — returns default for out-of-range index
10string? safe = items.ElementAtOrDefault(99);  // null

ElementAt(0) is functionally equivalent to First() but is index-based. It is useful when you need an element at a specific position, not just the first.

Direct Indexing (List<T> Only)

csharp
1// Fastest option — but only works with IList<T>
2var list = new List<int> { 10, 20, 30 };
3
4int first = list[0];  // Direct index access — O(1)
5
6// Check for empty first
7if (list.Count > 0)
8{
9    int safe = list[0];
10}
11
12// Arrays also support direct indexing
13int[] array = { 10, 20, 30 };
14int firstArr = array[0];

Direct indexing is the fastest option because it avoids iterator allocation. However, it only works with types that implement IList<T> (like List<T> and arrays), not with general IEnumerable<T>.

Using Enumerator Manually

csharp
1IEnumerable<int> sequence = GetNumbers();
2
3using var enumerator = sequence.GetEnumerator();
4if (enumerator.MoveNext())
5{
6    int first = enumerator.Current;
7    Console.WriteLine(first);
8}
9else
10{
11    Console.WriteLine("Empty sequence");
12}

Manually using the enumerator avoids LINQ overhead and works with any IEnumerable<T>. This is rarely needed but useful in performance-critical code or when avoiding a LINQ dependency.

Pattern Matching (C# 8+)

csharp
1var numbers = new List<int> { 10, 20, 30 };
2
3// Pattern matching with list patterns (C# 11)
4if (numbers is [var first, ..])
5{
6    Console.WriteLine(first);  // 10
7}
8
9// Deconstruction with Take
10var (firstItem, rest) = (numbers.First(), numbers.Skip(1));

Comparison Table

csharp
1// Performance and behavior comparison
2IEnumerable<int> source = Enumerable.Range(1, 1000000);
3
4// First() — iterates once, throws on empty
5source.First();              // Fast: O(1) for lists, O(1) iteration for IEnumerable
6
7// FirstOrDefault() — iterates once, returns default on empty
8source.FirstOrDefault();     // Fast: same as First()
9
10// ElementAt(0) — iterates once
11source.ElementAt(0);         // Fast: O(1) for IList, O(n) for IEnumerable at index n
12
13// list[0] — direct memory access
14((List<int>)source).ToList()[0];  // Fastest: no iterator, direct array access
15
16// Take(1).Single() — overkill
17source.Take(1).Single();    // Slower: creates extra iterator
MethodEmpty behaviorPerformanceWorks with
First()Throws exceptionO(1)Any IEnumerable<T>
FirstOrDefault()Returns defaultO(1)Any IEnumerable<T>
list[0]Throws IndexOutOfRangeO(1)IList<T> only
ElementAt(0)Throws exceptionO(1) for listsAny IEnumerable<T>

Common Pitfalls

  • Using First() on potentially empty collections: First() throws InvalidOperationException if the collection is empty. Use FirstOrDefault() when the collection might be empty, or check Any() before calling First().
  • Confusing FirstOrDefault() default with "not found": For int, FirstOrDefault() returns 0 both when the first element is 0 and when the collection is empty. Use FirstOrDefault(-1) (.NET 6+) or check Any() first to distinguish between "found 0" and "empty."
  • Multiple enumeration of IEnumerable<T>: Calling Any() then First() enumerates the sequence twice. If the source is a database query or network stream, this is expensive or incorrect. Use FirstOrDefault() and check for null/default instead.
  • Using Single() when First() is intended: Single() throws if the collection has more than one element. If you just want the first element regardless of collection size, use First(). Single() is for asserting uniqueness.
  • Null reference from FirstOrDefault() on reference types: For List<string>, FirstOrDefault() returns null on an empty list. Accessing properties on the result without a null check causes NullReferenceException. Use the null-conditional operator: result?.Length.

Summary

  • Use FirstOrDefault() as the safe default — it returns default(T) on empty collections
  • Use First() when the collection is guaranteed non-empty and you want fail-fast behavior
  • Use list[0] for direct index access on List<T> — fastest but requires bounds checking
  • In .NET 6+, use FirstOrDefault(fallback) to specify a custom default value
  • Avoid multiple enumeration — prefer FirstOrDefault() over Any() + First()
  • Be careful with value type defaults: 0 for int, false for bool may be valid values

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

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

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.