Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FirstOrDefault returning Unexpected Value

Tags:

c#

.net

linq

When I set a default value if the set is empty and call .FirstOrDefault() with a condition that isn't met I'm not getting my default value, but the type's default value:

int[] list = { 1, 2, 3, 4, 5 };
Console.WriteLine(list.DefaultIfEmpty(1).FirstOrDefault(i => i == 4)); // Outputs 4, as expected
Console.WriteLine(list.DefaultIfEmpty(1).FirstOrDefault(i => i > 5));  // Outputs 0, why??

This seems unintuitive since I'm setting .DefaultIfEmpty() to 1. Why doesn't this output a 1?

like image 865
Nick Gotch Avatar asked Nov 29 '22 02:11

Nick Gotch


2 Answers

You appear to misunderstand how DefaultIfEmpty works.

list.DefaultIfEmpty(1) returns a singleton sequence containing 1 if the source collection (list) is empty. Since list is not empty, this has no effect and the source sequence is returned.

As a result, your query is effectively the same as:

int result = list.FirstOrDefault(i => i > 5);

The default of int is 0 so FirstOrDefault returns 0 if the condition is not met, which it is not since list contains no elements greater than 5.

You can get the behaviour you want using:

int result = list.Cast<int?>().FirstOrDefault(i => i > 5) ?? 1;
like image 102
Lee Avatar answered Dec 05 '22 01:12

Lee


This is what you are looking for:

Console.WriteLine(list.Where(i => i > 5).DefaultIfEmpty(1).First());

By placing the Where before the DefaultIfEmpty, an empty collection will return an enumerable with one item. You can then use First to get that element.

like image 37
Simon Belanger Avatar answered Dec 05 '22 02:12

Simon Belanger