18

Enumerable.Single我在使用一些反编译器检查它时(大致)在方法中找到了这段代码:

foreach (TSource current in source)
{
    if (predicate(current))
    {
        result = current;
        num += 1L;
    }
}

if (num > 1L)
{
     throw Error.MoreThanOneMatch();
}

如您所见,它在投掷之前循环遍历所有项目。为什么它什么时候不坏num > 1

4

2 回答 2

4

同意,从性能方面来看会更好(编辑:如果我们期望有多个与我们的谓词匹配的项目,我们不应该这样做):

foreach (TSource current in source)
{
    if (predicate(current))
    {
        result = current;
        num += 1L;

        if (num > 1L)
            throw Error.MoreThanOneMatch();
    }
}

if (num == 0L)
   throw Error.NoMatch();

return local;

看起来他们决定使结果分析更清晰,并将其与枚举源分开。但后来我想知道为什么不使用简单的开关:

switch((int)num)
{
   case 0: throw Error.NoMatch();
   case 1: return local;
   default:
       throw Error.MoreThanOneMatch();    
}

关于性能问题 - 我认为当你真的期待 single resultSingle时应该调用它。零个或多个结果是一个异常路径,它不应该经常发生(作为任何异常)。因此,如果源包含许多匹配谓词的项目,则更多的是程序的逻辑错误。

于 2013-07-19T09:59:45.573 回答
0

Single意思是,恰好一个,不是没有,也不多于一个
它枚举所有项目,以确保它只是一个。
如果没有或不止一个,它会抛出一个异常。
SingleOrDefault如果有更多则抛出,但如果没有则返回default(T)/ null

您正在寻找的是FirstOrDefault打破枚举,如果它发现第一个匹配谓词。First如果没有,则抛出,如果找到第一个,也会中断(直接返回)它的 foreach。

FirstOrDefault 的来源

foreach (TSource current in source)
{
    if (predicate(current))
    {
        return current;
    }
}
return default(TSource);

而 First 的来源不是返回默认值

throw Error.NoMatch();
于 2013-07-19T10:15:59.690 回答