Not a lot has changed with LINQ over the years. But I still find that developers aren’t completely familiar with the differences with some of the methods. In this post I’ll show the differences between:

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

Of course these methods are similar but there are times when using the wrong one could lead to big problems with your application. The obvious similarity between these methods is that they are meant to return a single item. This is quite different from methods like Where() which returns a collection of items.

Now let’s focus on the differences.

I have noticed that in most cases, developers tend to use First() as the go to method for returning a single item from a collection. In my opinion, this is a bad idea. I tend to use Single() more often but of course there are times when each is appropriate. Here’s why…

Let’s start with a data set to work from. Here are some members of two great bands:

	List<Person> list = new List<Person>();
	list.Add(new Person {Id = 1, FirstName = "John", LastName = "Lennon"});
	list.Add(new Person {Id = 2, FirstName = "Paul", LastName = "McCartney"});
	list.Add(new Person {Id = 3, FirstName = "George", LastName = "Harrison"});
	list.Add(new Person {Id = 4, FirstName = "Ringo", LastName = "Starr"});
	list.Add(new Person {Id = 5, FirstName = "Jimmy", LastName = "Page"});
	list.Add(new Person {Id = 6, FirstName = "Robert", LastName = "Plant"});
	list.Add(new Person {Id = 7, FirstName = "John", LastName = "Bohnam"});
	list.Add(new Person {Id = 8, FirstName = "John Paul", LastName = "Jones"});

Let’s assume that the Id field is unique.

First, the method Single()

If I want to select a user by Id, I could use Single()

Person x = people.Single(p => p.Id == 1);

That will return the Person object for John Lennon.

For Single, the big difference comes when things aren’t as I expect them to be. Consider the following examples.

Person x = people.Single(p => p.Id == 9);

In this case, there is no person with an Id of 9. So Single() will throw an exception: “Sequence contains no matching element”.

Here’s another scenario

Person x = people.Single(p => p.FirstName == "John");

This too will throw an exception. This time it is “Sequence contains more than one matching element”.

So which is the best to use? It really depend on the situation. Often when you are selecting an item by Id, it is because you already know the Id. And if you do, I think it is safe to expect that the object with that Id exists. So I use Single(). In this case, the exception will be thrown if the user doesn’t exist but maybe that is ok because exceptions are for when things go wrong and in this case, something must have gone wrong. I also showed using Single(p => p.FirstName == “John”). But why would I do that? What reason could I have for selecting a Single item by a field that is not unique? Was I just curious to know if we had any Johns in the system? Would I have been better off with Any(p => p.FirstName == “John”) that returns a boolean?

Another option is SingleOrDefault()

Person x = people.SingleOrDefault(p => p.Id == 1);

This too will return the object for John Lennon.

Person x = people.SingleOrDefault(p => p.Id == 9);

SingleOrDefault() is safer. This time instead of an exception, x will be Null. Of course, as the developer, only I can decide which is better (Single or SingleOrDefault). It really depends on what I expect to happen and what other code exists to deal with unexpected results.

Person x = people.SingleOrDefault(p => p.FirstName == "John");

And SingleOrDefault() will still throw an exception if there is more than one “John”: “Sequence contains more than one matching element”

Next, a look at First() and FirstOrDefault()

Often, First() will give similar results but I find it misleading and using First() where inappropriate may actually hide problems. Consider the following:

Person x = people.First(p => p.Id == 1);

This too returns the object John Lennon.

Seems like everything is fine. But what if our data was bad. What if somehow we had two people with Id 1. Before you say “that would never happen”, think about some of the systems that you have supported. What if there was a mistake in the data entry validation? What if there was a bad import. My point is, it could happen. So now, if we use First(), we will get the first item in the collection that has the matching Id. It seems to me like in this case, I’d rather have Single throw an exception for me!

Unlike Single(), First() will NOT throw an exception if there is more than one matching element. Consider this:

Person x = people.First(p => p.FirstName == "John");

You can’t just assume that the result is John Lennon. It could depend on your data source and how the data was entered. Also, if a statement also had an OrderBy()

Person x = people.OrderBy(o => o.LastName).First(p => p.FirstName == "John");

Now I’m getting John Bohnam.

Yes, there are definitely cases when this is OK. But most of the time, I’d bet it is not. Why would I ever want the First() John?

Person x = people.FirstOrDefault(p => p.FirstName == "John");

This would have the same result as above. I could get John Lennon or John Bohnam depending on other factors.

Person x = people.FirstOrDefault(p => p.FirstName == "Pete");

Here, I get Null again (no exception). Sorry Pete Best, you’re not in the list.

So which to use?

There are circumstances for all of these. It’s great that we have 4 options. The important part is that as the developer, you understand that these are different. Please just don’t fall back on First() and use it all the time. Think about which is right for the circumstances you have at the moment.

One last tip

These statements may work correctly but they are just wasting keystrokes. I always say “less is more” with code.

Person x = people.Where(p => p.Id == 1).Single();
Person x = people.Where(p => p.Id == 1).First();

Please don’t do that. It’s much simpler to just say:

Person x = people.Single(p => p.Id == 1);
Person x = people.First(p => p.Id == 1);

Philly.Net recently had a very successful event called CSharpenUp. We spent the day talking about some advanced topics for C# developers. We had 4 speakers and 80+ attendees. The feedback was very positive, everyone learned a lot and had fun too. If we can set it up, we’ll do the same event in the fall for those that missed it.

I’m still gathering code samples from the other presenters. But for now, here is mine:

Code samples and slides for my LINQ session: Intro to LINQ

Code samples and slides for my Unit Testing session: Unit Testing Made Easy

Also, FYI we did try to record the sessions using Camtasia. Unfortunately, the mic we used wasn’t that great. I’m trying to salvage mine but I may just re-record them.

Linq is awesome and always makes tasks easier!  Here is a great tip that you might not know about.

Today I needed to compare two generic lists… SequenceEqual() to the rescue.  To show how it works, here is some sample code:

[Test]
public void SuccessfullyMatchesTwoListsOfInts()
{
    List<int> ints1 = new List<int>();
    ints1.Add(1);
    ints1.Add(2);
    ints1.Add(3);

    List<int> ints2 = new List<int>();
    ints2.Add(1);
    ints2.Add(2);
    ints2.Add(3);

    Assert.That(ints1.SequenceEqual(ints2), Is.True);
}

SequenceEqual loops through the 2 lists and compares each item to make sure they match.  Just for kicks I put it through the paces.  Here are some other unit tests that I wrote.  This helps show what you can do:

using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;

namespace SequenceEqual
{
    [TestFixture]
    public class SequenceEqualTests
    {
        [Test]
        public void SuccessfullyMatchesTwoListsOfInts()
        {
            List<int> ints1 = new List<int>();
            ints1.Add(1);
            ints1.Add(2);
            ints1.Add(3);

            List<int> ints2 = new List<int>();
            ints2.Add(1);
            ints2.Add(2);
            ints2.Add(3);

            Assert.That(ints1.SequenceEqual(ints2), Is.True);
        }

        [Test]
        public void SuccessfullyFailsTwoListsOfInts()
        {
            // these two don't match!
            List<int> ints1 = new List<int>();
            ints1.Add(1);
            ints1.Add(2);
            ints1.Add(3);

            List<int> ints2 = new List<int>();
            ints2.Add(1);
            ints2.Add(4);
            ints2.Add(3);

            Assert.That(ints1.SequenceEqual(ints2), Is.False);
        }

        [Test]
        public void SuccessfullyFailsTwoListsOfIntsOutOfOrder()
        {
            // these two don't match. They have the same contents but the order is changed.
            List<int> ints1 = new List<int>();
            ints1.Add(3);
            ints1.Add(2);
            ints1.Add(1);

            List<int> ints2 = new List<int>();
            ints2.Add(1);
            ints2.Add(2);
            ints2.Add(3);

            Assert.That(ints1.SequenceEqual(ints2), Is.False);
        }

        [Test]
        public void SuccessfullyFailsTwoListsOfStrings()
        {
            // these two lists of strings don't match
            List<string> strings1 = new List<string>();
            strings1.Add("one");
            strings1.Add("two");
            strings1.Add("three");

            List<string> strings2 = new List<string>();
            strings2.Add("one");
            strings2.Add("lasjdflkajsdf");
            strings2.Add("three");

            Assert.That(strings1.SequenceEqual(strings2), Is.False);
        }

        [Test]
        public void SuccessfullyMatchesTwoListsOfStrings()
        {
            // two matching lists of strings.
            List<string> strings1 = new List<string>();
            strings1.Add("one");
            strings1.Add("two");
            strings1.Add("three");

            List<string> strings2 = new List<string>();
            strings2.Add("one");
            strings2.Add("two");
            strings2.Add("three");

            Assert.That(strings1.SequenceEqual(strings2), Is.True);
        }

        [Test]
        public void SuccessfullyMatchesTwoListsOfObjects()
        {
            // works for objects too.
            List<TestObject> objects1 = new List<TestObject>();
            objects1.Add(new TestObject { Property1 = "1" });
            objects1.Add(new TestObject { Property1 = "2" });
            objects1.Add(new TestObject { Property1 = "3" });

            Assert.That(objects1.SequenceEqual(objects1), Is.True);
        }

        [Test]
        public void SuccessfullyFailsTwoListsOfObjects()
        {
            // these two lists of objects may "look" the same, but they aren't
            // the same object (reference equals!)
            List<TestObject> objects1 = new List<TestObject>();
            objects1.Add(new TestObject { Property1 = "1" });
            objects1.Add(new TestObject { Property1 = "2" });
            objects1.Add(new TestObject { Property1 = "3" });

            List<TestObject> objects2 = new List<TestObject>();
            objects2.Add(new TestObject { Property1 = "1" });
            objects2.Add(new TestObject { Property1 = "2" });
            objects2.Add(new TestObject { Property1 = "3" });

            Assert.That(objects1.SequenceEqual(objects2), Is.False);
        }

        [Test]
        public void SuccessfullyMatchesTwoListsOfObjectsWithCustomComparer()
        {
            // here I use a custom comparer to see if the 
            // two lists of objects have the same content.
            List<TestObject> objects1 = new List<TestObject>();
            objects1.Add(new TestObject { Property1 = "1" });
            objects1.Add(new TestObject { Property1 = "2" });
            objects1.Add(new TestObject { Property1 = "3" });

            List<TestObject> objects2 = new List<TestObject>();
            objects2.Add(new TestObject { Property1 = "1" });
            objects2.Add(new TestObject { Property1 = "2" });
            objects2.Add(new TestObject { Property1 = "3" });

            Assert.That(objects1.SequenceEqual(objects2, new TestObjectComparer()), Is.True);
        }

        [Test]
        public void SuccessfullyFailsTwoListsOfObjectsWithCustomComparer()
        {
            // making sure the custome comparer fails when they don't match
            List<TestObject> objects1 = new List<TestObject>();
            objects1.Add(new TestObject { Property1 = "1" });
            objects1.Add(new TestObject { Property1 = "2" });
            objects1.Add(new TestObject { Property1 = "3" });

            List<TestObject> objects2 = new List<TestObject>();
            objects2.Add(new TestObject { Property1 = "1" });
            objects2.Add(new TestObject { Property1 = "asdfsadf" });
            objects2.Add(new TestObject { Property1 = "3" });

            Assert.That(objects1.SequenceEqual(objects2, new TestObjectComparer()), Is.False);
        }
    }

    public class TestObject
    {
        public string Property1 { get; set; }
    }

    public class TestObjectComparer : IEqualityComparer<TestObject>
    {
        public bool Equals(TestObject x, TestObject y)
        {
            return (x.Property1 == y.Property1);
        }

        public int GetHashCode(TestObject obj)
        {
            return obj.GetHashCode();
        }
    }
}

Today I needed to compare to generic lists. I guessed that Linq would provide a way to do this and sure enough it did: SequenceEqual() to the rescue. To show how it work

You’ve heard about LINQ to SQL, LINQ to Objects and LINQ to XML right?  Well how about LINQ to String?  Well technically there is no such thing.  But you use LINQ on a string!  You may not have realized this before but it works.  LINQ can be used to query IEnumerable<T> and a string is actually a collection of chars.  So yup, you can actually query the string itself.  Here are a few simple examples but you certainly do a lot more than this…

public void LinqToStringSample()
{
    string letters = "keuiwierqewefqwfwefcjlkjkl";

    //count all 'e'
    int count = letters.Count(l => l == 'e');

    //order
    var ordered = letters.OrderBy(l => l);
    
}

Tomorrow I’m presenting “Introduction to LINQ” at the Microsoft Event: Data Access Firestarter.  I’m trying to be proactive and actually post my samples and slides in advance!  This way, they’ll be there if anyone wants to take a look.  I’ll be doing the same demo at Philly.Net Code Camp on April 10 too.

Click here to download the samples: Demo and Slides 

If you attended the Firestarter, I hope you enjoyed my talk.  If not, I hope to see you at Code Camp.  And if you just happened along and are interested in learning LINQ, enjoy the samples.  Email me if you have any questions.