Can somebody explain how DefaultIfEmpty()
can be used in LINQ. I have ready some material but still need something solid to see what the use of it is.

- 5,210
- 5
- 31
- 50

- 44,246
- 124
- 269
- 414
-
1What don't you understand about its usage? – Oded Jan 13 '12 at 16:52
-
3I don't really understand what you would use it for, either. It returns an `IEnumerable
`, so if you used `.DefaultIfEmpty().First()` it's the same as `.FirstOrDefault()`... [The examples on MSDN](http://msdn.microsoft.com/en-us/library/bb360179.aspx) are really bad. – Ry- Jan 13 '12 at 16:53 -
1One use is so you don't have to break up the code with `if (x != null)` tests. – ChrisF Jan 13 '12 at 16:53
-
@ChrisF: You still do, though. It returns an `IEnumerable`. – Ry- Jan 13 '12 at 17:01
-
@minitech - you're right - my mistake. – ChrisF Jan 13 '12 at 17:06
-
[This](http://stackoverflow.com/q/8752209/1078151) is a question that I post not long ago that isn't the same as yours, but I ended up using DefaultIfEmpty. I don't claim that it's "the" way to use it, but it serves as another example. – That Chuck Guy Jan 13 '12 at 17:46
3 Answers
It basically returns a collection with a single element in case the source collection is empty.
var numbers = new int[] {1, 2, 3};
var aNumber = numbers.First();
returns 1
but
var numbers = new int[];
var aNumber = numbers.DefaultIfEmpty(12).Single();
returns 12 as the collection is empty

- 37,131
- 7
- 73
- 89
-
Oh, okay. A little silly that you can't do `.FirstOrDefault(12)` instead, though. – Ry- Jan 13 '12 at 17:03
-
3DefaultIfEmpty returns an element whereas DefaultIfEmpty returns a collection which can then be cascaded to another linq operation in the chain. – vc 74 Jan 13 '12 at 17:07
-
5@vc74: was that first `DefaultIfEmpty` meant to be `FirstOrDefault` (in your comment)? – Chris Jan 13 '12 at 17:20
-
@Chris Yes, thanks for pointing out, please read FirstOrDefault returns an element instead – vc 74 Jan 13 '12 at 20:07
The difference is the DefaultIfEmpty returns a collection of objects while FirstOrDefault returns an object. If there were no results found DefaultIfEmpty still returns an Enumerable with a single item that has its default value, whereas FirstOrDefault returns T itself.
You use DefaultIfEmpty if you need always need a collection result, for instance to create outer joins. You use FirstOrDefault if you always need an object (not a collection) result, for instance if you want to get the first item (or only item) when searching for something like an ID or unique email, and want to return the default empty item if the item you were searching for was not found.

- 476
- 5
- 5
A particularly useful application of DefaultIfEmpty()
is to avoid multiple enumerations in the case where you can't just workaround an empty list using Append
.
For example, consider you have a (potentially empty) set of numbers and want the average value. If the set is empty you consider 0
as being a reasonable value to use by client code.
You could try
var avg = numbers.Append(0).Average() ;
but that doesn't actually give the correct results for a non-empty list!
You could write
var avg = numbers.Any() ? numbers.Average() : 0 ;
but this enumerates your set twice and that could be big problem if it's a deferred query.
But
var avg = numbers.DefaultIfEmpty(0).Average();
does just what you want - you get the average unless the list is empty in which case you get 0.
It's also nicely composable so a good building block for these kinds of methods...
public static T FuncOr<T>(this IEnumerable<T> items,
Func<IEnumerable<T>, T> func,
T fallback)
=> func(items.DefaultIfEmpty(fallback));
public static T MaxOr<T>(this IEnumerable<T> items, T fallback)
=> items.FuncOr(i=>i.Max(), fallback);
public static T MinOr<T>(this IEnumerable<T> items, T fallback)
=> items.FuncOr(i=>i.Min(), fallback);
//etc

- 3,339
- 2
- 20
- 22