2014-09-13 109 views
3

在预先排序的List<int>中,我将找到满足条件的最后一个元素,例如int lastScore = list.Last(x => x < 100)。如果列表中没有满足此条件的元素,则会抛出InvalidOperationException,并显示错误消息:Sequence contains no matching element。这也发生在list.First(...)Enumerable.Last()引发InvalidOperationException“序列中不包含匹配元素”

我甚至试图让lastScore为空也无济于事。

捕捉异常并手动指定lastScorenull唯一的出路?

+0

欢迎SO!说了这些,我很困惑你的问题。 'List '不能是'list'的类型,因为'int'当然没有'Score'属性。请澄清。 – J0e3gan 2014-09-13 05:07:39

+0

真的很抱歉!我打算写'list.Last(x => x <100)'。感谢您指出它。我也编辑了这个问题。 – 2014-09-13 05:11:49

回答

3

使用FirstOrDefaultLastOrDefault得到null如果不匹配,假设您正在使用引用类型。这些方法将返回值为default value的值类型。

+1

在这种情况下('IEnumerable ')它将返回0,而不是null。如果0是有效值,这实际上是有问题的。一种解决方案是首先将序列转换为IEnumerable ,尽管在这种情况下我可能只是处理异常。 – user2864740 2014-09-13 05:14:57

+0

是的。那么,解决方案是什么? – 2014-09-13 05:18:17

+0

刚发现'FirstOrDetault'和'LastOrDefault'为值类型返回默认值(例如'int's为0)。对于'IEnumerable '其中'T'是一个引用类型,它们返回'null'。 – 2014-09-13 13:54:32

0

我可能只是在最接近的使用点捕捉异常

这是因为LastOrDefault/FirstOrDefault超过一个IEnumerable<int>将返回0(对于int默认值),其可以一个“有效”值 - 这取决于实际的上下文和定义的规则。虽然将序列转换为IEnumerable<int?>将允许以前的方法返回null,这似乎是更多的工作,而不是价值。

如果需要对一个继续使用使用lastScore,考虑:

int? lastScore; /* Using a Nullable<int> to be able to detect "not found" */ 
try { 
    lastScore = list.Last(x => x < 100); /* int -> int? OK */ 
} catch (InvalidOperationException) { 
    lastScore = null; /* If 0 see LastOrDefault as suggested; 
         otherwise react appropriately with a sentinel/flag/etc */ 
} 
if (lastScore.HasValue) { 
    /* Found value meeting conditions */ 
} 

或者,如果能够抛弃时没有找到的情况下,可以考虑:

try { 
    var lastScore = list.Last(x => x < 100); 
    /* Do something small/immediate that won't throw 
     an InvalidOperationException, or wrap it in it's own catch */ 
    return lastScore * bonus; 
} catch (InvalidOperationException) { 
    /* Do something else entirely, lastScore is never available */ 
    return -1; 
} 
相关问题