A new way to use the linq FirstOrDefault, now with lambdas

Ever since I learned about the joys of linq and especially linq's FirstOrDefault, I have written my code in the same manner as I think about querying a database. Get the list, set in the criteria, grab the first, rinse and repeat. Things changed when I recently bought Resharper, and one of the first things I noticed was an annoying line under my code telling me I can do better.

Resharper warning me to improve my code

At first I thought this message was too good to be true, after all, I had never seen this in any code. I have long since learned not to trust things at face value, even though the code compiles. I quickly wrote up a unit test to verify that Resharper was actually right, that I could write less code, use a fancy lambda expression, and get the same result. I also verified that the SingleOrDefault and First extensions work this way as well.

        [Test]
        public void FirstOrDefaultExample()
        {
            var people = new People().Persons;

            var tim = people.Where(p => p.PersonId == 1).FirstOrDefault();
            var timNew = people.FirstOrDefault(p => p.PersonId == 1);

            var jack = people.Where(p => p.FirstName == "Jack").Single();
            var jackNew = people.Single(p => p.FirstName == "Jack");

            Assert.AreEqual(tim, timNew);
            Assert.AreEqual(jack, jackNew);
        }

    public class People
    {
        public List Persons { get; set; }

        public People()
        {
            Persons = new List();

            Persons.Add(Person.CreatePerson(1, "Tim", "Sneed"));
            Persons.Add(Person.CreatePerson(2, "Dirk", "Pitt"));
            Persons.Add(Person.CreatePerson(3, "Jack", "Ryan"));
            Persons.Add(Person.CreatePerson(4, "Mitch", "Rapp"));
            Persons.Add(Person.CreatePerson(5, "Thomas", "Jefferson"));

        }
    }

    public class Person
    {
        public int PersonId { get; private set; }
        public string FirstName { get; private set; }
        public string LastName { get; private set; }

        private Person()
        {

        }

        public static Person CreatePerson(int personId, string firstName, string LastName)
        {
            return new Person() { FirstName = firstName, LastName = LastName, PersonId = personId };
        }
    }

And wouldn't you know it, Resharper was right! I don't know how I missed this in all the years I have been using this language, but there you go.

Test was successful, Resharper wins again.

After adjusting to the lack of an explicit where clause, I find this much more simple and elegant.

Sample code can be found here for the curious.

comments powered by Disqus