2013-07-17 123 views
4

当我设置一个默认值,如果设置为空,并呼吁.FirstOrDefault()与不满足我没有收到我的默认值的条件,但类型的默认值:FirstOrDefault返回意外值

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?? 

这似乎很不直观,因为我将.DefaultIfEmpty()设置为1.为什么不输出1?

+5

整数的默认值(因为没有找到)是一个0. –

+0

为什么不用我使用'.DefaultIfEmpty'设置的值,因为没有返回的值符合条件? –

+3

因为'DefaultIfEmpty'适用于'list'而不是结果。 – Romoku

回答

12

您似乎误解了DefaultIfEmpty的工作原理。

list.DefaultIfEmpty(1)如果源集合(list)为空,返回包含1的单例序列。由于list不为空,因此不起作用,并返回源序列。

其结果是,查询实际上是相同的:

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

int默认为0所以FirstOrDefault返回0如果条件不满足,它不是因为list不包含元素,更大大于5

你可以得到你想要使用的行为:

int result = list.Cast<int?>().FirstOrDefault(i => i > 5) ?? 1; 
1

整数的缺省值是0

FirstOrDefault返回第一个发生或默认值,在你的情况下,你重新使用int,所以它是0。如果您想要在没有物品时发生异常,请尝试使用First(x => x > 5)

1

FirstOrDefault指的是表达式default(T)的值,其中T是集合的类型,而不是列表的第一个值。您无法更改该行为,也无法更改某个类型的默认值。

1

的默认值表不可为空INT默认值为0。由于没有在你的列表是> 5,它返回默认值。

0

DefaultIfEmpty不设置默认值。如果原始列表为空,它将为您提供一个列表,其中包含此值作为默认值。

9

这是你在找什么:

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

通过DefaultIfEmpty前放置Where,一个空的集合会返回一个枚举一个项目。然后您可以使用First来获取该元素。

+0

谢谢,是的,这是我期待的行为。 –