Tired of FirstOrDefault returning NULL when working with custom objects and LINQ? Then write your own
So I finally got to work with LINQ in our current .NET 3.5 project as I haven’t had a chance to use it yet in business projects, just personal projects which usually resulted from curiosity. I know, I know, it’s newness has worn off since it’s been around since .NET 3.0 but hey, whattyagonnado? Anywho, I began working with LINQ centered around some custom classes and collections we had written.
As I being working with this, I specifically came across a few use-case scenarios for FirstOrDefault(). I could use this function with a conditional clause and knock out a lot of clunk codeblocks that I used in different parts of the application. Then I quickly found the pitfall of using this with my custom object… it returned NULL if not found. This required me to write 2 more lines of code to checks for NULLs which I felt was a bit wasteful so I was steered by Google to http://blog.dynamicprogrammer.com/2009/05/28/FirstOrNullObjectExtensionMethodForIEnumerableAndFirstOrNew.aspx which taught me to write my own FirstOrDefault type of function which allows me to define the default value that is returned if a value is not found. If you want actual information about it, please read his post above. I’m just providing the code I wrote as a result of reading his excellent post.
Here is my LINQHelper class I came up with. These extension methods give me the ability to prevent the returning of a NULL object with my custom classes which reduces the amount of code I have to write in the long run. I also went ahead and extended the LastOrDefault methods as well.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BusinessLogic
{
public static class LINQHelper
{
public static T FirstOrNullObject<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T nullObject)
{
var val = enumerable.FirstOrDefault<T>(func);
if (val == null)
{
val = nullObject;
}
return val;
}
public static T FirstOrNullObject<T>(this IEnumerable<T> enumerable, T nullObject)
{
var val = enumerable.FirstOrDefault<T>();
if (val == null)
{
val = nullObject;
}
return val;
}
public static T FirstOrNew<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T newObject)
{
return enumerable.FirstOrNullObject<T>(func, newObject);
}
public static T FirstOrNew<T>(this IEnumerable<T> enumerable, T newObject)
{
return enumerable.FirstOrNullObject<T>(newObject);
}
public static T FirstOrDefault<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T defaultObject)
{
return enumerable.FirstOrNullObject<T>(func, defaultObject);
}
public static T FirstOrDefault<T>(this IEnumerable<T> enumerable, T defaultObject)
{
return enumerable.FirstOrNullObject<T>(defaultObject);
}
public static T LastOrNullObject<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T nullObject)
{
var val = enumerable.LastOrDefault<T>(func);
if (val == null)
{
val = nullObject;
}
return val;
}
public static T LastOrNullObject<T>(this IEnumerable<T> enumerable, T nullObject)
{
var val = enumerable.LastOrDefault<T>();
if (val == null)
{
val = nullObject;
}
return val;
}
public static T LastOrNew<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T newObject)
{
return enumerable.LastOrNullObject<T>(func, newObject);
}
public static T LastOrNew<T>(this IEnumerable<T> enumerable, T newObject)
{
return enumerable.LastOrNullObject<T>(newObject);
}
public static T LastOrDefault<T>(this IEnumerable<T> enumerable, Func<T, bool> func, T defaultObject)
{
return enumerable.LastOrNullObject<T>(func, defaultObject);
}
public static T LastOrDefault<T>(this IEnumerable<T> enumerable, T defaultObject)
{
return enumerable.LastOrNullObject<T>(defaultObject);
}
}
}
Once again, this information was gathered from Mr. Garcia’s blog at http://blog.dynamicprogrammer.com. I give him full credit for this information laid out in a very explanatory blog post.
blog comments powered by Disqus