wolfgang ziegler


„make stuff and blog about it“

LINQ, why is there no SecondOrDefault?

October 31, 2014

Why is there a FirstOrDefault extension method but no SecondOrDefault?

That’s what a fellow programmer friend asked me recently and I agreed about the potential usefulness of such a method.

linq y u no

But the thing is that LINQ is all about building blocks and you can easily achieve the “get second or default” functionality with existing means.

var item = items.Skip(1).FirstOrDefault();

Of course, this is not as readable as it could be. So let’s wrap it into a custom extension method called SecondOrDefault.

public static T SecondOrDefault<T>(this IEnumerable<T> items)
{
  return items.Skip(1).FirstOrDefault();
}

That way we could also have a ThirdOrDefault extension method.

public static T ThirdOrDefault<T>(this IEnumerable<T> items)
{
   return items.Skip(2).FirstOrDefault();
}

Or more generically, a NthOrDefault extension method, which let’s us specify the n-th argument, we are interested in.

public static T NthOrDefault<T>(this IEnumerable<T> items, int n)
{
   return items.Skip(n).FirstOrDefault();
}

Like this:

var item = items.NthOrDefault(42);

Now we can also refactor the existing SecondOrDefault extension method to reuse our more versatile NthOrDefault method.

public static T SecondOrDefault<T>(this IEnumerable<T> items)
{
   return NthOrDefault(items, 1);
}

Reusing the more versatile method also comes in handy and if we decided to refactor the method, or add some error checking. We have to touch the actual logic only once and SecondOrDefault, ThirdOrDefault, … benefit from it.

public static T NthOrDefault<T>(this IEnumerable<T> items, int n)
{
   if (items == null)
   {
     throw new ArgumentNullException("items");
   }
   return items.Skip(n).FirstOrDefault();
 }