Skip to main content

Command Palette

Search for a command to run...

Differences between Single and First in C#

Published
2 min read

In this tutorial we will take a closer look at few methods used to retrieve items from collections:

  • Single()
  • SingleOrDefault()
  • First()
  • FirstOrDefault()

Firstly, we will prepare our list:

List<Student> students = new List<Student>();

students.Add(new Student() { Id = 1, Name = "John", Course = "Computer Science" });
students.Add(new Student() { Id = 2, Name = "Mark", Course = "Biology" });
students.Add(new Student() { Id = 3, Name = "Mark", Course = "Chemistry" });
students.Add(new Student() { Id = 4, Name = "David", Course = "Archeology" });

Single()

This method returns only one matching element or throws an exception.

If there is exactly one result it is returned:

var student = students.Single(s => s.Name == "John");
System.Console.WriteLine(student.Id);

// 1

If there are several matching elements it will throw exception:

var student = students.Single(s => s.Name == "Mark");

// System.InvalidOperationException: Sequence contains more than one matching element

If there is no matching element it will throw exception:

var student = students.Single(s => s.Name == "Bob");

// System.InvalidOperationException: Sequence contains no matching element

SingleOrDefault()

This function is similar to Single() but returns default value of some type if there is no matching element:

var student = students.Single(s => s.Name == "Bob");
System.Console.WriteLine(student == null);

// True
// student is null

Imagine that you have some list of integers and want to find the first number equals to some criteria (don't ask about reason to have such a list, it is for educational purposes only :) ):

List<int> numbers = new List<int> {1, 2, 3};

var number = numbers.SingleOrDefault(s => s == 4);
System.Console.WriteLine(number);

// 0

The default value for an integer is 0 (zero).

First()

This method returns the first matching element for provided criteria.

var student = students.First(s => s.Name == "Mark");
System.Console.WriteLine(student.Id);

// 2

If there is no matching record it throws an exception:

var student = students.First(s => s.Name == "Charlie");

// System.InvalidOperationException: Sequence contains no matching element

FirstOrDefault()

Similarly as in the case of Single and SingleOrDefault, FirstOrDefault returns the first matching element or default value for the used type if there is no found record.

var student = students.FirstOrDefault(s => s.Name == "Charlie");
System.Console.WriteLine(student == null);

// True

And here is example with primitive type:

List<int> numbers = new List<int> {1, 2, 3};

var number = numbers.FirstOrDefault(s => s == 4);
System.Console.WriteLine(number);

// 0

It is good to remember the difference and use specific methods depending on your needs. Pay attention to data types and their default values when using SingleOrDefault and FirstOrDefault methods.

153 views
K
kndb4y ago

Thanks for the article Kamil, good refresher.
I hate null handling, so recently I have been using these methods a bit differently, where I specify what is the default value.

var defaultStudent = new Student 
{ 
Id = 0,
Name = "Karen", 
Course = "FlatEarth" 
};
var student = students.Where(s => s.Name == "Charlie").DefaultIdEmpty(defaultStudent).FirstOrDefault();

Hopefully MS would allow us to manage default values directly in the future.

1
K

kndb thank you for your valuable comment. I haven't used DefaultIdEmpty before. It looks interesting.

1