65.9K
CodeProject is changing. Read more.
Home

FirstOrDefault Extension Method the Way I Expect It to Work

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.33/5 (3 votes)

Nov 8, 2010

CPOL

1 min read

viewsIcon

39110

downloadIcon

94

Creating a FirstOrDefault Extension Method that takes the default value as a parameter

Introduction

In this article, I'm going to show how to create and use an extension method for an IEnumerable collection.

Background

Whenever I need to pull a specific object out of a list, I always end up writing the same code to check to make sure the item exists in the collection, if it does return the item, if not return a default.

if (stateList.Count(x => x.Code == "ME") > 0)
{
    Console.WriteLine(stateList.FirstOrDefault(x => x.Code == "ME", defaultState).Name);
}
else
{
    Console.WriteLine(defaultState.Name);
}

Solution

IEnumerable already has a FirstOrDefault method, but it didn't work the way I expected. I expected to be able to pass in the default value I wanted to have returned if no items existed that met my criteria.

The first step is to create a static class to hold the extension methods.

namespace FirstOrDefaultExtension.IEnumerableExtensionMethods
{
    internal static class IEnumerableExtensionMethods
    {
    }
} 

Next, you define the extension method. The method must be static.

public static TSource FirstOrDefault3<TSource>
  (this IEnumerable<TSource> enumerable, Func<TSource, bool> pred, TSource defaultValue)
{
	foreach (var x in enumerable.Where(pred))
	{
		return x;
	}
	return defaultValue;
}  

(Thanks to Dimzon who provided this meat of this method that performs well, my first attempted worked, but didn't perform.)

The enumerable parameter is the IEnumerable collection that the method will be acting on. By defining it with this, we are indicating that this method will be available as an extension method of classes that implement IEnumerable. The TSource is the type of objects in the collection, and in this case we are returning an object of that type.

Using the code is simple, which is good because simplicity was the whole point of the code.

var stateList = new List<State>();

stateList.Add(new State("ME", "Maine"));
stateList.Add(new State("NH", "New Hampshire"));
stateList.Add(new State("VT", "Vermont"));
stateList.Add(new State("MA", "Massachusetts"));
stateList.Add(new State("RI", "Rhode Island"));
stateList.Add(new State("CT", "Connecticut"));

var defaultState = new State("", "Non New England State Code");

Console.WriteLine(stateList.FirstOrDefault(x => x.Code == "ME", defaultState).Name);
Console.WriteLine(stateList.FirstOrDefault(x => x.Code == "NY", defaultState).Name); 

The output of this code would be:

Maine 

Non New England State Code 

History

  • 11/08/10 - v1 First posted
  • 11/08/10 - v2 Fixed performance issues pointed out in article comments
FirstOrDefault Extension Method the Way I Expect It to Work - CodeProject