James Michael Hare

...hare-brained ideas from the realm of software development...
posts - 136 , comments - 1076 , trackbacks - 0

My Links

News

Welcome to my blog! I'm a Sr. Software Development Engineer in Seattle, WA. I've been doing C++/C#/Java development for over 18 years, but have definitely learned that there is always more to learn!

All thoughts and opinions expressed in my blog and my comments are my own and do not represent the thoughts of my employer.

Blogs I Read

MCC Logo MVP Logo

Follow BlkRabbitCoder on Twitter

Tag Cloud

Archives

Post Categories

C#/.NET Little Wonders: First() and Single() - Similar Yet Different

Once again, in this series of posts I look at the parts of the .NET Framework that may seem trivial, but can really help improve your code by making it easier to write and maintain.

Today we're going to look at two LINQ extension methods that are both very similar and yet very different.  Logically, First() and Single() serve similar purposes, but there is a subtle difference between these two that if you aren't expecting it may give you very different behaviors.

First() - Retrieves the first occurrence

The First() method, as its name implies, finds the first item in a sequence.  Now, there are actually four flavors of this method, each with their own twist.  Each of these are extensions methods that operate on any IEnumerable<TSource>:

  • First()
    • Returns the very first item in the sequence, if no item exists throws InvalidOperationException.
  • First(Func<TSource, bool>)
    • Returns the very first item in the sequence that matches the predicate, if no item exists that matches throws InvalidOperationException.
  • FirstOrDefault()
    • Returns the very first item in the sequence, if the sequence is empty returns default(TSource).
  • FirstOrDefault(Func<TSource, bool>)
    • Returns the very first item in the sequence that matches the predicate, if no item exists that matches returns default(TSource).

The first thing of note is that the First() method returns the first item (or first match in the case of the predicate version).  This means if there is more than one item in the list (or more than one match) only the first item is returned.  This also means that the moment the first item is found, the method exits immediately and does not scan the remainder of the enumerable.

Let's take a look at how this behaves.  For the purposes of this illustration let's assume we have this POCO defined:

   1: public sealed class Employee
   2: {
   3:     public long Id { get; set; }
   4:     public string Name { get; set; }
   5:     public double Salary { get; set; }
   6: }

And that we've loaded up three lists for illustrative purposes.  One with no elements, one with one element, and one with many elements:

   1: // empty
   2: var noEmployeeList = new List<Employee>();
   3:  
   4: // one item
   5: var oneEmployeeList = new List<Employee>
   6:     {
   7:         new Employee { Id = 55, Name = "Sussie Queue", Salary = 60000.50 }
   8:     };
   9:  
  10: // many items
  11: var employees = new List<Employee>
  12:     {
  13:         new Employee { Id = 1, Name = "Jim Smith", Salary = 12345.50 },
  14:         new Employee { Id = 7, Name = "Jane Doe", Salary = 31234.50 },
  15:         new Employee { Id = 9, Name = "John Doe", Salary = 13923.99 },
  16:         new Employee { Id = 13, Name = "Jim Smith", Salary = 30123.49 },        
  17:         // ... etc ...
  18:     };

Now, if we apply our First() methods to this, we can see how it will behave.  In both cases, the method will return the first item they are looking for regardless of how many items (or match duplicates) the list may contain.

   1: // gets the first Jim Smith with Id of 1
   2: var first = employees.First();
   3:  
   4: // gets the first employee whose name starts with John.
   5: var firstJohn = employees.First(e => e.Name.StartsWith("John"));
   6:  
   7: // gets the first employee whose name ends with Doe, even though there are
   8: // many, in this case it gets Jane Doe, Id = 7
   9: var firstDoe = employee.First(e => e.Name.EndsWith("Doe"));

The second thing to notice is that the two First() method overloads will throw if no items exist (or no matches exist in the predicate version):

   1: // throws at runtime because empty enumerable.
   2: var empty = noEmployees.First();
   3:  
   4: // this line will throw at runtime because there is no item that matches
   5: // even though the enumerable itself is not empty
   6: var noMatch = employees.First(e => e.Id == 20);

And then finally, notice that the two FirstOrDefault() methods behave similarly to their First() counterparts in that they return the first match, but instead of throwing an InvalidOperationException they will instead return the default(TSource) if no items exist (or no matches exist in the predicate version).  Now, remember that the default operator will return the default value for any type.  For numerics this is zero, for bool this is false, for reference types this is null, etc.

   1: // instead of throwing, this returns default(Employee) which is null
   2: var empty = noEmployees.FirstOrDefault();
   3:  
   4: // this also returns null since no match exists
   5: var noMatch = employees.FirstOrDefault(e => e.Id == 20);

Single() - Returns the one and only occurrence

So now that we've seen how First() and its cousin works, let's look at Single().  Just like First(), Single() scans an enumerable looking either for the first item or the first match -- however, that's where the similarity ends!  Remember that First() only cares about the first item it finds and ignores any other items or matches.  Single() on the other hand will throw an InvalidOperationException if it is not the only item (or match) in the list!

The overloads for Single() and its cousin SingleOrDefault() are very similar to First() and FirstOrDefault():

  • Single()
    • Returns the only item in the sequence, if no item exists throws InvalidOperationException, and if more than one item exists, also throws InvalidOperationException.
  • Single(Func<TSource, bool>)
    • Returns the only item in the sequence that matches the predicate, if no item exists that matches throws InvalidOperationException, and if more than one item exists that matches the predicate, also throws InvalidOperationException.
  • SingleOrDefault()
    • Returns the only item in the sequence, if the sequence is empty returns default(TSource), but if more than one item exists throws InvalidOperationException.
  • SingleOrDefault(Func<TSource, bool>)
    • Returns the only item in the sequence that matches the predicate, if no items match predicate returns default(TSource), or if more than one item matches throws InvalidOperationException.

Notice the main key difference here between the Single family and the First family is that if there is more than one item (or match) in the list it will always throw InvalidOperationException.  Also notice that this means that even if the form of Single() that takes a predicate finds its match early on, it still potentially has to scan up to the remainder of the enumerable to make sure there wasn't a duplicate.  This can make Single() a bit less efficient if you have other ways of assuring that you won't have duplicates in the enumerable.

   1: // gets the one and only item from the list (Sussie Queue)
   2: var oneAndOnly = oneEmployeeList.Single();
   3:  
   4: // throws because not exactly one item in list.
   5: var throwsOnEmpty = noEmployeeList.Single();
   6:  
   7: // throws because more than one item in list.
   8: var throwsOnMultiple = employeeList.Single();

Also notice that in the version that takes a predicate a similar rule holds true where it will behave like the predicate version of First() except if there is more than one match it will throw the InvalidOperationException:

   1: // gets the one and only item from the list with ID == 7
   2: var oneAndOnlyMatch = oneEmployeeList.Single(e => e.Id == 7);
   3:  
   4: // throws because there are no matches
   5: var throwsOnNoMatches = noEmployeeList.Single(e => e.Id == 999);
   6:  
   7: // throws because there are multiple matches
   8: var throwsOnMultipleMatches = employeeList.Single(e => e.Name.EndsWith("Doe"));

Finally, just like with FirstOrDefault(), SingleOrDefault() will return a default(TSource) if no items (or no matches) are found:

   1: // now, instead of throwing provides a default for the type (null for reference types) if empty.
   2: var defaultsOnEmpty = noEmployeeList.SingleOrDefault();
   3:  
   4: // now, instead of throwing provides a default for the type (null for reference types) if no match.
   5: var defaultsOnNoMatch = noEmployeeList.SingleOrDefault(e => e.Id == 999);

Summary – when to use each?

So here we saw two similar, yet different, classes of extension methods to get the first (or first matching) item in a list. The main difference being that the First() family looks for the first item (or match) then stops and ignores other matches, whereas the Single() family looks for the one and only item (or match) and if it finds multiple it will throw an exception.

Both have the option of removing the exception when no item (or match) is found with the …OrDefault() versions, but Single() will always throw if there are duplicates, by design (because if you didn’t want it to obviously you’d use First()).

So my general advice on using these two very handy method families is to use the First() family when you either don’t care about duplicates or are reasonably sure through other means (like it comes from a database table with a primary key constraint) that there are no duplicates.

Single is handy if you need to verify an enumerable and want to ensure no duplicates when you don’t have direct control over the integrity of the original data, but keep in mind that means that any call to the predicate version of Single() may potentially search the whole list to check for a duplicate where the predicate version of First() will just stop on the first match.

Finally, if you aren’t sure if an item exists, favor the …OrDefault() flavors of these two method families, though these are typically more useful for enumerables of reference types, since null is a good indicator nothing was found, whereas if you search an enumerable of int and it’s not found, it will return 0 which is also possibly a valid value in the enumerable.

Print | posted on Thursday, April 14, 2011 7:09 PM | Filed Under [ My Blog C# Software .NET Little Wonders ]

Feedback

Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

This was extremely helpful. I've attempted to use Single() and never understood why I sometimes get an exception, now everything is clear. This post also made me realize I was doing so pretty inefficient things when searching for things in an Enumerable. Like I said, very helpful.
4/15/2011 10:53 AM | Jesse Williamson
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

As always, well done.
4/15/2011 1:34 PM | Michael Washington
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

@Michael, @Jesse thanks!
4/15/2011 4:32 PM | James Michael Hare
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

Thank you for a great blog post.

In the spirit of the functional side of LINQ, I would personally have used Enumerable.Empty<Employee>() for the noEmployeeList, and arrays for the other two sequences in order to achieve immutability since none of the sequences are mutated.
4/18/2011 12:53 AM | Martin Rosén-lidholm
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

I was never quite sure which to use in certain situations. Its always lovely explaining to your manager why you used a call only to be "semi-guessing". Thanks for explaining.
4/20/2011 6:22 PM | Kyler
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

Ya, well said , thanks, gr8 info.
4/20/2011 11:13 PM | Hiya
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

@Martin: True if they would be static (as in non-changing, not as in the keyword) collections in real life. I was just using them as three possible dataset examples stored in a List<T>.
4/21/2011 9:38 AM | James Michael Hare
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

Thanks for this great post. As Michael pointed it out — as always, well done.
4/25/2011 6:03 AM | Marius Schulz
Gravatar

# great

Michael thanks for informative article
4/26/2011 10:59 AM | Freeborg
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

@Freeborg, @Marius, @Jack: Thanks!
4/26/2011 2:57 PM | James Michael hare
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

Thanks for your great post keep it up and keep posting.
4/27/2011 5:13 AM | Renjith Maxy
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

2 typos:
(or first match in the case of the FirstOrDefault())
=> (or first match with the Predicate version):

in SingleOrDefault(Predicate<TSource>) description, you forgot "but if more than one item exists" before "also throws InvalidOperationException."
7/28/2011 6:42 AM | Wizou
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

@Wizou: Thanks for the heads up on the typo! I'll correct it when I get home tonight.
7/28/2011 9:06 AM | James Michael Hare
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

Good job man, also thanks for spotting the typo Wizou something was not working!

Cheers
9/20/2011 4:48 PM | Gilles
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

Great article. I wasn't sure about the difference and this explained it very well. However, I have one comment. Being new to c# please explain what POCO means. I now know that it mean plain old class object. but when I first read it, I didn't know.
11/17/2011 3:38 PM | schutte-licious
Gravatar

# re: C#/.NET Little Wonders: First() and Single() - Similar Yet Different

@schutte-licious:

A POCO is a Plain Old CLR Object (or alternatively Plain Old C# Object) which is essentially the .NET equivalent of the POJO (Plain Old Java Object) concept.

All a POCO is, is a very flat class that only contains properties with no real method functionality. In effect, it takes the place of what we used to use struct for in C++ with all public fields and no methods.

These are typically just used to store flat data in, such as for storing records from a database, web service, etc. For example:

public sealed class Employee
{
public string Name { get; set; }
public int ID { get; set; }
public string Address { get; set; }
public double Salary { get; set; }
}

And so on, just data, not real methods...
11/17/2011 8:21 PM | James Michael Hare
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 
 

Powered by: