Click here to Skip to main content
15,884,177 members
Articles / Programming Languages / C#

FirstOrDefault Extension Method the Way I Expect It to Work

Rate me:
Please Sign up or sign in to vote.
2.33/5 (3 votes)
8 Nov 2010CPOL1 min read 38.3K   94   11
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.

C#
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.

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

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

C#
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.

C#
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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
I’m a Software Engineer at Microsoft working on the Azure Portal. Before that I spent about 20 years developed various business applications at a number of different companies. I have a passion for writing clean, scalable code and sharing what I’ve learned with others.

I also help run the Casco Bay .Net User Group

Comments and Discussions

 
Generalcollection.Where(x => x > 10).DefaultIfEmpty(defaultValue).First() Pin
kjaniszewski8-Nov-10 12:55
kjaniszewski8-Nov-10 12:55 
GeneralRe: collection.Where(x => x > 10).DefaultIfEmpty(defaultValue).First() Pin
Jeremy Hutchinson9-Nov-10 1:53
professionalJeremy Hutchinson9-Nov-10 1:53 
Generalvote 1/5 - awfull code! Pin
dimzon8-Nov-10 6:39
dimzon8-Nov-10 6:39 
GeneralRe: vote 1/5 - awfull code! Pin
Jeremy Hutchinson8-Nov-10 10:22
professionalJeremy Hutchinson8-Nov-10 10:22 
General[My vote of 1] enumerating multiple times is bad for performance Pin
Wim Reymen8-Nov-10 6:33
Wim Reymen8-Nov-10 6:33 
GeneralRe: [My vote of 1] enumerating multiple times is bad for performance Pin
dimzon8-Nov-10 6:50
dimzon8-Nov-10 6:50 
GeneralRe: [My vote of 1] enumerating multiple times is bad for performance Pin
Jeremy Hutchinson8-Nov-10 11:41
professionalJeremy Hutchinson8-Nov-10 11:41 
GeneralMy vote of 1 Pin
dimzon8-Nov-10 6:28
dimzon8-Nov-10 6:28 
Questionwhy not like this? Pin
TimMerksem8-Nov-10 6:27
TimMerksem8-Nov-10 6:27 
AnswerRe: why not like this? Pin
dimzon8-Nov-10 6:49
dimzon8-Nov-10 6:49 
AnswerRe: why not like this? Pin
Jeremy Hutchinson8-Nov-10 11:48
professionalJeremy Hutchinson8-Nov-10 11:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.