-
Tired of FirstOrDefault returning NULL when working with custom objects and LINQ? Then write your own!
Posted on June 8th, 2009 2 commentsSo 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.
2 responses to “Tired of FirstOrDefault returning NULL when working with custom objects and LINQ? Then write your own!”

-
Thank’s a lot!
-
Theodore March 3rd, 2010 at 16:27
Awesome code! Thanks.
And think I got one improvement. Instead of passing in a new default object every time, I used reflection.
public static T FirstOrNew(this IEnumerable enumerable, Func func) {
var val = enumerable.FirstOrDefault(func);
if (val == null) {
val = (T)Activator.CreateInstance();
}return val;
}public static T FirstOrNew(this IEnumerable enumerable) {
var val = enumerable.FirstOrDefault();
if (val == null) {
val = (T)Activator.CreateInstance();
}
return val;
}
Leave a reply
-


Kurko February 12th, 2010 at 01:46